#include "component.h"
#include "device.h"
#include "motor_dai_3opto.h"

#include "export.h"
#include "debug_config.h"

#include IOCFG_H
#include "application.h"

/************************************************************************************/
//更新时间：2024-08-14
//修    改：陈
//1，调整自识别过程
//2，优化开、关锁不到位，回锁不到位问题：增加定时器，根据电压查表，延迟状态设置
//3，校准过程，屏蔽指纹，按键，NEF，按键等的消息粗处理
//4，识别成功，增加消息通知
/************************************************************************************/
// 将其他配置放置xxx_iocfg.h中
//HALL1-->B22、HALL2-->B24、HALL3-->B23、OCEP1-->B20、OCEP1-->B21
#ifndef HALL1_SET_LEVEL
#define HALL1_SET_LEVEL (1)
#endif
#define HALL1_RESET_LEVEL (!HALL1_SET_LEVEL)

#ifndef HALL2_SET_LEVEL
#define HALL2_SET_LEVEL (0)
#endif
#define HALL2_RESET_LEVEL (!HALL2_SET_LEVEL)

#ifndef HALL3_SET_LEVEL
#define HALL3_SET_LEVEL (0)
#endif
#define HALL3_RESET_LEVEL (!HALL3_SET_LEVEL)

#ifndef OCEP1_SET_LEVEL
#define OCEP1_SET_LEVEL (0)
#endif
#define OCEP1_RESET_LEVEL (!OCEP1_SET_LEVEL)

#ifndef OCEP2_SET_LEVEL
#define OCEP2_SET_LEVEL (0)
#endif
#define OCEP2_RESET_LEVEL (!OCEP2_SET_LEVEL)

#ifndef OCEP3_SET_LEVEL
#define OCEP3_SET_LEVEL (0)
#endif
#define OCEP3_RESET_LEVEL (!OCEP3_SET_LEVEL)

#ifndef MOTOR_POWER_ENABLE_LEVEL
#define MOTOR_POWER_ENABLE_LEVEL (1)
#endif
#define MOTOR_POWER_DISABLE_LEVEL (!MOTOR_POWER_ENABLE_LEVEL)

#ifndef IR_POWER_ENABLE_LEVEL
#define IR_POWER_ENABLE_LEVEL (1)
#endif
#define IR_POWER_DISABLE_LEVEL (!IR_POWER_ENABLE_LEVEL)

#ifndef LOCK_SYSTEM_ID
#define LOCK_SYSTEM_ID COMP_LOCK
#endif
/* 电机供电电压控制脚（电压高时降压）*/
#ifndef MOTOR_POWER_CTRL_VAL 
#define MOTOR_POWER_CTRL_VAL 5500
#endif
/* 电机供电电压控制脚 高电压时输出电平*/
#ifndef MOTOR_HIGH_VOLTAGE_LEVEL 
#define MOTOR_HIGH_VOLTAGE_LEVEL 0
#endif
/* 电机供电电压控制脚 高电压时输出电平*/
#ifndef MOTOR_SLEEP_VOLTAGE_LEVEL 
#define MOTOR_SLEEP_VOLTAGE_LEVEL 0
#endif

/* 电机回拖时间根据电压控制（电压高时转速快）*/
#ifndef MOTOR_BACK_VAL_LEVEL1 
#define MOTOR_BACK_VAL_LEVEL1 6000
#endif

#ifndef MOTOR_BACK_VAL_LEVEL2 
#define MOTOR_BACK_VAL_LEVEL2 5600
#endif

#ifndef MOTOR_BACK_VAL_LEVEL3 
#define MOTOR_BACK_VAL_LEVEL3 5100
#endif

#ifndef MOTOR_BACK_VAL_LEVEL4 
#define MOTOR_BACK_VAL_LEVEL4 4800
#endif

#ifndef MOTOR_BACK_TIME_LEVEL1 
#define MOTOR_BACK_TIME_LEVEL1 280 //320
#endif

#ifndef MOTOR_BACK_TIME_LEVEL2 
#define MOTOR_BACK_TIME_LEVEL2 380 //410
#endif

#ifndef MOTOR_BACK_TIME_LEVEL3 
#define MOTOR_BACK_TIME_LEVEL3 410
#endif

#ifndef MOTOR_BACK_TIME_LEVEL4 
#define MOTOR_BACK_TIME_LEVEL4 480
#endif

#ifndef AUTO_LOCK_MODE 
#define AUTO_LOCK_MODE 0
#endif

#ifndef NORMAL_OPEN_MODE 
#define NORMAL_OPEN_MODE 1
#endif

/* 电机电流采集的ADC通道 */
#define LOCK_DCI_ADC_CHANNEL                    vADC_1
#define MOTO_A_VIRTUAL_PWM                      vPWM_1
#define MOTO_B_VIRTUAL_PWM                      vPWM_2
#define SENSOR_HALL_LEFT                        vPIN_B22
#define SENSOR_HALL_RIGHT                       vPIN_B23
#define SENSOR_HALL_CENTER                      vPIN_B24


#define LOCK_IR_ENABLE()                        Device_Write(vPIN_C0, NULL, 0, IR_POWER_ENABLE_LEVEL) //开启红外光耦电源
#define LOCK_IR_DISABLE()                       Device_Write(vPIN_C0, NULL, 0, IR_POWER_DISABLE_LEVEL) //关闭红外光耦电源

#define LOCK_MOTOR_ENABLE()                     Device_Write(vPIN_C2, NULL, 0, MOTOR_POWER_ENABLE_LEVEL) //开启电机驱动电源
#define LOCK_MOTOR_DISABLE()                    Device_Write(vPIN_C2, NULL, 0, MOTOR_POWER_DISABLE_LEVEL) //关闭电机驱动电源

#define LOCK_MOTOR_POWER_HIGH_VOLTAGE()         Device_Write(vPIN_C45, NULL, 0, MOTOR_HIGH_VOLTAGE_LEVEL); // 电机输入电压高
#define LOCK_MOTOR_POWER_LOW_VOLTAGE()          Device_Write(vPIN_C45, NULL, 0, !MOTOR_HIGH_VOLTAGE_LEVEL); // 电机输入电压低
#define LOCK_MOTOR_POWER_SLEEP_VOLTAGE()        Device_Write(vPIN_C45, NULL, 0, MOTOR_SLEEP_VOLTAGE_LEVEL); // 休眠IO配置

/* 事件 */
#define EVENT_MOTOR_MONITOR                     (0X00000001)  //电机监控事件
#define EVENT_AUTO_LOCK                         (0X00000002)  //自动上锁事件
#define EVENT_LOCK_DIR_UPDATE                   (0X00000004)  //上电同步上锁方向
#define EVENT_LOCK_STUDY_DIR                    (0X00000008)  //自学习找到开锁位置，执行上锁，找上锁位置
#define EVENT_LOCK_SENSER_CHANGE_WAKE           (0X00000010)  //开关锁光耦改变唤醒，需要上报事件，上层判断是否执行自动上锁

#define NO_BRAKE             //无刹车
#define OPEN_TO_BRAKE        //开门刹车
#define CLOSE_TO_BRAKE       //关门刹车
#define BACK_NO_BRAKE	     //回锁无刹车
#define STOP_TO_BRAKE      //停车刹车
#define POSITION_DELAY_COMP  //到位时间补偿

#define OPEN_CLOSE_DELAY_START    1 //开\关锁延迟功能启动状态
#define OPEN_DELAY_RUN            2 //开锁延迟功能进行状态
#define CLOSE_DELAY_RUN           4 //关锁延迟功能进行状态




/* 电机控制参数 */
#define MOTOR_PARAM_MAX_REPEAT_TIMES            3       //最大重复次数（上锁/开锁失败后，会自动重复3次）
#define MOTOR_PARAM_MAX_DCI_VALUE               30//165// 400 //电压为200mv 采样电阻0.5Ω 换算成电机堵转限制电流400mA // TODO:堵转电流待定
#define MOTOR_PARAM_LOCKED_MORE_TIME            50      //上锁过推时间
#define MOTOR_PARAM_BLOCK_STOP_TIMEOUT          1000    //堵转停止超时时间
#define MOTOR_PARAM_STOP_TIME1                  200     //电机暂停时间1（开锁堵转暂停时间、开关锁超时）
#define MOTOR_PARAM_TURN_TIMEOUT                4000    //电机正常运行，超时时间
#define MOTOR_PARAM_BACK_TIMEOUT                400  // 520 //2000    //电机回拖运行，超时时间
#define MOTOR_PARAM_DCI_DETECT_DELAY_TIME       80      //电机启动后，电流检测延迟时间
#define MOTOR_PARAM_NO_BRAKE_CHANGE_DIR_TIME    1000 //    //换方向时间 切换方向时间必须>1s(包含刹车时间)
#define MOTOR_PARAM_BRAKE_TIME                  500     //电机刹车时间  刹车时间需要确认是否充足
#define MOTOR_PARAM_CHANGE_DIR_TIME             500     //换方向时间 切换方向时间必须>1s(包含刹车时间)
#define MOTOR_PARAM_STOP_TO_BRAKE_TIME          10      //10ms 



/* 电机监测时间间隔 */
#define MOTOR_MONITOR_TIME                      (10)    //电机监测时间间隔 10ms
#define AUTO_LOCK_EVENT_TIME                    (1) //(2)     //自动上锁事件
/* 电机上锁堵转重新操作锁体的时间间隔 */
#define MOTOR_BLOCKED_LOCKED_TIME               (1000)
/* 电机开锁堵转重新操作锁体的时间间隔 */
#define MOTOR_BLOCKED_UNLOCK_TIME               (100)  

#define MOTOR_BLOCKED_FILETERED_TIME            (30)    //堵转过滤时间 50ms
#define MOTOR_BLOCKED_FILETERED_TIMES           (MOTOR_BLOCKED_FILETERED_TIME/MOTOR_MONITOR_TIME)

#define SENSOR_MAX_RING_LEN                     (10) // 整个锁体流程最多8个数据变化 + 光耦上电时最多2个

/****NV item ID****/
typedef enum
{
    NVAUTO_CALFLAG,
    NVMOTO_DIR,
} LockNvItemID_enum_t;
/****NV item ID****/

/****NV sub ID****/
//不需要sub ID
/****NV sub ID****/

/* 锁体状态 */
static enum {
    LOCK_STA_UNKNOW,     //未知状态
    LOCK_STA_LOCKING,    //正在上锁
    LOCK_STA_UNLOCKING,  //正在开锁
    LOCK_STA_LOCKED,     //已上锁
    LOCK_STA_UNLOCK,     //已开锁
} lockStatus = LOCK_STA_UNKNOW;


/* 传感器状态类型 */
typedef enum
{
	LOCK_SENSOR_UNKNOW,  //传感器状态未知
	LOCK_SENSOR_SET,     //传感器状态：到位（感应到了）
	LOCK_SENSOR_LONG_SET,//传感器状态：长时间到位（长按）
	LOCK_SENSOR_RESET,   //传感器状态：未到位（没感应到）
}SensorStatus_enum_t;

/* 自动上锁/开锁步骤*/
typedef enum
{
	LOCK_STEP_START,           //启动
	LOCK_STEP_FOUND_DEST,      //上锁/开锁到位
	LOCK_STEP_BACKED,          //上锁/开锁回拖到位
	LOCK_STEP_RESET,           //传感器状态：未到位（没感应到）
}LockStep_enum_t;

static TimerHandle_stu_t Auto_Lock_Timer = NULL;


#define VOLTAGE_LEVEL_MAX 11

/* 电机状态数据 */
static struct
{
	volatile MotorStatus_enum_t current; //电机当前状态 
	volatile uint32_t startTime;         //电机当前状态开始时间
	volatile uint32_t timeout;           //电机当前状态超时时间
}motorStatus = {MOTOR_STA_IDLE, MOTOR_STA_IDLE};

uint8_t inti_dir=0XFF;

/* 电机运行错误情况 */
volatile static enum
{
	ERR_NO_ERROR,       //无错误0
	ERR_LOCK_ERROR,     //锁体错误（电机运转结束时，传感器状态不对）1
 
	ERR_LOCKED_TIMEOUT, //上锁超时2
	ERR_UNLOCK_TIMEOUT, //开锁超时3
	ERR_BACK_TIMEOUT,   //回拖超时4
    ERR_RESET_TIMEOUT,  //回位超时5
 
	ERR_LOCKED_DCI,     //上锁过流6
	ERR_UNLOCK_DCI,     //开锁过流7
	ERR_BACK_DCI,       //回拖过流8
    ERR_RESET_DCI,      //回位过流9
}motorError = ERR_NO_ERROR;

/* 电机刹车原因类型 */
typedef enum
{
	MOTOR_BRAKE_NO_SOURCE,              //无刹车源
    MOTOR_BRAKE_LOCKED,                 //上锁刹车
    MOTOR_BRAKE_UNLOCK,                 //开锁刹车
    MOTOR_BRAKE_RESET,                  //回位刹车
}MotorBrakeSource_enum_t;

/* 上锁方向类型 */
typedef enum
{
	LOCKED_DIR_UNKNOWN,                 //未知上锁方向
    LOCKED_DIR_CW,                      //顺时针上锁方向
    LOCKED_DIR_CCW,                     //逆时针上锁方向
}Locked_Dir_enum_t;//旋钮

/* 上锁堵住阶段控制类型 */
typedef enum
{
	LOCKED_BLOCK_INIT,                  //初始状态
    LOCKED_BLOCK_LOCKED,                //上锁堵转,当前阶段为上锁阶段
    LOCKED_BLOCK_UNLOCK,                //上锁堵转,当前阶段为开锁阶段
}Locked_Block_Phase_enum_t;


/* 传感器测试阶段类型 */
typedef enum
{
	SENSOR_TESTSETP_INIT,               //初始状态
    SENSOR_TESTSETP_START,              //启动阶段
    SENSOR_TESTSETP_END,                //结束阶段
    SENSOR_TESTSETP_RESET,              //回位阶段
    SENSOR_TESTSETP_RESET_BACK,         //回位回拖阶段
}Lock_Sensor_TestSetp_enum_t;

static RingBufferHandle_t rbHandle = NULL;
static  FlagStatus g_unlockChgFlag = SET;//开锁传感器变化标志;  SET:变化   RESET:没变化
static  FlagStatus g_lockChgFlag = SET;  //关锁传感器变化标志;  SET:变化   RESET:没变化


 typedef union 
 {
   uint16_t i;
   struct
   {
     uint16_t   Msg_Open_Close   :4;
     uint16_t   Calib_Open_Delay :3;
     uint16_t   Calib_Close_Delay:3; 
   }b;
 }calib_st_t;
 
__EFRAM static calib_st_t calib_st;

/* 锁体模式 */
__EFRAM static Locked_Mode_enum_t lockedMode = LOCKED_MODE_NORMAL;

/* 锁校准标志 */
__EFRAM static FlagStatus lockCalibFlag = RESET;
//__EFRAM static FlagStatus Msg_Open_Close = 0xff;

/* 上锁方向 */
__EFRAM static Locked_Dir_enum_t lockedDir = LOCKED_DIR_UNKNOWN;

/* 上锁堵转标志 */
static FlagStatus lockedBlock = RESET;

/* 上锁执行回拖标志 */
static FlagStatus lockedBack = RESET;

/* 开锁执行回拖标志 */
static FlagStatus unLockBack = RESET;

/* 上锁堵转后的锁体控制阶段 */
static Locked_Block_Phase_enum_t lockedBlockPhase = LOCKED_BLOCK_INIT;

/* 传感器测试阶段 */
static Lock_Sensor_TestSetp_enum_t sensorTestSetp = SENSOR_TESTSETP_INIT;

/* 传感器测试结果 */
static uint16_t sensorTestRet = 0;
static uint8_t buttonFlage = 0xff;//按鍵状态，标志

volatile static uint8_t repeatCount;        //重复上锁计数
volatile static uint8_t isrPendFlag;        //中断挂起标志
volatile SensorStatus_enum_t leftLockedSensor = LOCK_SENSOR_UNKNOW;     //左侧(面向磁铁)上锁传感器
volatile SensorStatus_enum_t rightLockedSensor = LOCK_SENSOR_UNKNOW;    //右侧(面向磁铁)上锁传感器
__EFRAM volatile SensorStatus_enum_t lockedSensor = LOCK_SENSOR_UNKNOW;         //上锁传感器(左右上锁传感器两个都没上锁则没上锁,否则即是已上锁)
__EFRAM volatile SensorStatus_enum_t unlockSensor = LOCK_SENSOR_UNKNOW;         //开锁传感器
__EFRAM volatile SensorStatus_enum_t backLockedSensor = LOCK_SENSOR_UNKNOW;     //开锁到位、上锁回拖到位传感器
__EFRAM volatile SensorStatus_enum_t backUnlockSensor = LOCK_SENSOR_UNKNOW;     //上锁到位、开锁回拖到位传感器
volatile static uint8_t g_IrPowerSwitch = RESET;//光耦电源开关标志，默认关
static uint8_t g_BrakeFlag = DISABLE;//ENABLE:刹车动作标志   

LockNvData_stu_t lock_data = { \
.g_autoCalFlag = 0,
.motor_direction = MOTO_DIR_CW,
.version = FIRMWARE_VER,
};

static uint8_t g_lockWakeFlag = RESET;//唤醒标志
static uint8_t g_SleepSenserCheck = SET;//自动模式下，未自动上锁，不需要检测唤醒，前板定时自动上锁

static MOTO_STATUS_E       moto_status                 = MOTO_STOP_LOCK_UNKNOWN;    //锁体当前状态（转动、关锁、开锁）
static LockStep_enum_t     g_current_step              = LOCK_STEP_START;                //锁体当前步骤（启动、到位、回拖、回位）

static uint16_t bat_vol = MOTOR_POWER_CTRL_VAL; // 默认电压值
static uint16_t motor_back_timeout = MOTOR_PARAM_BACK_TIMEOUT; // 默认回拖超时

static uint8_t current_lockMode = AUTO_LOCK_MODE; // 当前上锁模式

static ErrorStatus Lock_Ctrl_Sub(LockCtrl_enum_t ctrl);
extern int32_t GPIO_WakeupCheckReadPinIo(uint32_t pin_num);
extern int32_t GPIO_WakeupCheckPowerOn(uint32_t pin_num, uint8_t power);
void Lock_Init_Update_Senser(void);
void lock_step_found_dest_handle(uint8_t dest_type);
static void Lock_OptocoupleCtrl(uint8_t ir_power_level);
/* 电机状态数据 */
struct 
{
	uint8_t   StepCount;
	uint8_t   lockstatue;
	uint8_t   index;
}motorRunDelyOpen,motorRunDelyClose;


typedef  struct 
{
	uint16_t  voltage;
	uint8_t   openDelaytime;
	uint8_t   closeDelaytime;
	uint16_t  backDelaytime;
	uint16_t  openbackDelaytime;
}motoOnOffDelya;



//电压，开延迟，关延迟，开回锁延迟，关回锁，单位：ms

const motoOnOffDelya motorOnOffDely[VOLTAGE_LEVEL_MAX]=
{
#ifndef BACK_NO_BRAKE
	{6300,19,19,310,315},
	{6100,21,21,330,320},
	{6000,22,22,340,340},
	{5800,27,27,360,360},	
	{5600,33,30,380,380},	
	{5400,38,33,400,400},	
	{5200,40,40,420,420},	
	{5000,50,42,460,460},	
	{4800,58,50,480,480},	
	{4600,60,50,510,510},	
	{4200,65,52,540,540},
#else
	{6300,20,20,310,310},
	{6100,20,20,340,340},
	{6000,20,20,350,350},
	{5800,30,30,360,360},	
	{5600,30,30,380,380},	
	{5400,40,40,410,410},	
	{5200,40,40,440,440},	
	{5000,50,50,470,470},	
	{4800,60,60,490,490},	
	{4600,60,60,520,520},	
	{4200,70,70,550,550},
#endif
};



uint8_t MotoDelaySet(uint16_t batvol)
{ uint8_t vbtVol=VOLTAGE_LEVEL_MAX-1;
  uint8_t i;
	
	for(i=0;i<VOLTAGE_LEVEL_MAX;i++)
	{
		if(batvol>motorOnOffDely[i].voltage) 
		{
			vbtVol=i;
			break;
		}
	}
	LOCKDAI_LOG_D("bat_vol:%d;vbtVol=%d;Calib=%d",bat_vol,vbtVol,lockCalibFlag);
	LOCKDAI_LOG_V("openBack:%d;closeBack=%d;\n",motorOnOffDely[vbtVol].openbackDelaytime,motorOnOffDely[vbtVol].backDelaytime);
	LOCKDAI_LOG_V("openDelay:%d;closeDelay=%d;\n",motorOnOffDely[vbtVol].openDelaytime,motorOnOffDely[vbtVol].closeDelaytime);
	return vbtVol;
}

uint8_t get_battery(void)
{
    return (bat_vol*100)/6300;
}



#if 0
static void motoDelay_timer_handler(co_timer_t *timer, void *param)
{
	if(motorRunDelyOpen.StepCount==2) g_current_step=motorRunDelyOpen.lockstatue;
	else if(motorRunDelyClose.StepCount==4) g_current_step=motorRunDelyClose.lockstatue;
	co_timer_del(&motoDelay_timer);
	LOCKDAI_LOG_D("motoDelay_timer over %d\r\n",motorRunDelyOpen.StepCount);
	motorRunDelyOpen.StepCount=0xff;
	motorRunDelyClose.StepCount=0xff;
}
#else

static void motoDelay_timer_handler(TimerHandle_stu_t handle)
{
	if(motorRunDelyOpen.StepCount==OPEN_DELAY_RUN) g_current_step=motorRunDelyOpen.lockstatue;
	else if(motorRunDelyClose.StepCount==CLOSE_DELAY_RUN) g_current_step=motorRunDelyClose.lockstatue;
	LOCKDAI_LOG_D("motoDelay_timer over\r\n");
	
	motorRunDelyOpen.StepCount=0xff;
	motorRunDelyClose.StepCount=0xff;
}

#endif

uint8_t Get_lockCalibFlag_Status(void)
{
	return lockCalibFlag;
}

/**
 * @brief  获取锁状态
 * @note
 *
 *
 */
static uint8_t Lock_get_lock_status(void) //open,close,unknown
{
    if(motorStatus.current != MOTOR_STA_IDLE)
    {
        moto_status = MOTO_ROTATE;
    }
    else
    {
        if(lockStatus == LOCK_STA_LOCKING || lockStatus == LOCK_STA_LOCKED)
        {
            moto_status = MOTO_STOP_LOCK_CLOSE;
        }
        else if(lockStatus == LOCK_STA_UNLOCKING || lockStatus == LOCK_STA_UNLOCK)
        {
            moto_status = MOTO_STOP_LOCK_OPEN;
        }
        else
        {
            moto_status = MOTO_STOP_LOCK_UNKNOWN;
        }
    }
    return moto_status;
}

/**
 * @brief 更新开关锁传感器状态
 * 
 * @param 
 *  #define OPTO3_PIN     1  // vPIN_B33
    #define OPTO2_PIN     11 // vPIN_B20
    #define OPTO1_PIN     13 // vPIN_B21
    {vPIN_B21, (uint32_t)OPTO1_PIN}
    {vPIN_B20, (uint32_t)OPTO2_PIN}
    {vPIN_B33, (uint32_t)OPTO3_PIN}
 */
void Lock_WakeupUpdateSenser(void)
{
    if(g_IrPowerSwitch == RESET) 
    {
          Lock_OptocoupleCtrl(IR_POWER_ENABLE_LEVEL);
    }

    if (GPIO_WakeupCheckReadPinIo(OPTO2_PIN) == OCEP1_SET_LEVEL || GPIO_WakeupCheckReadPinIo(OPTO3_PIN) == OCEP1_SET_LEVEL)
    {
        lockedSensor = LOCK_SENSOR_SET;
    }
    else
    {
        lockedSensor = LOCK_SENSOR_RESET;
    }

	
    // if (Device_Read(vPIN_B21, NULL, 0, 0) == OCEP1_SET_LEVEL)
    if (GPIO_WakeupCheckReadPinIo(OPTO1_PIN) == OCEP1_SET_LEVEL)
    {
        unlockSensor = LOCK_SENSOR_SET;
    }
    else
    {
		unlockSensor = LOCK_SENSOR_RESET;
    }
}
/**
 * @brief 获取当前锁状态是否改变
 * 
 * @param 
 *  #define OPTO3_PIN     1  // vPIN_B33
    #define OPTO2_PIN     11 // vPIN_B20
    #define OPTO1_PIN     13 // vPIN_B21
    {vPIN_B21, (uint32_t)OPTO1_PIN}
    {vPIN_B20, (uint32_t)OPTO2_PIN}
    {vPIN_B33, (uint32_t)OPTO3_PIN}
 */
uint32_t Lock_WakeupCheckSenser(void)
{
    if (current_lockMode == AUTO_LOCK_MODE && g_SleepSenserCheck == SET)
    {
        LOCKDAI_LOG_D("auto mode %d\r\n", g_SleepSenserCheck);
        // 当前是自动模式，则检查传感器状态是否开锁状态
        if (lockCalibFlag)
        {
            // 唤醒标志置位
            if (GPIO_WakeupCheckPowerOn(OPTO_EN_PIN, SET))
            {
                 LOCKDAI_LOG_D("CheckSenser OCEP\r\n");
				g_IrPowerSwitch = SET; 
                co_delay_ms(1);
				Lock_WakeupUpdateSenser();
                
                // TODO:判断左右开 --- 只判断一路IO状态
                
			    //if (Device_Read(vPIN_B20, NULL, 0, 0) == OCEP1_SET_LEVEL || Device_Read(vPIN_B33, NULL, 0, 0) == OCEP1_SET_LEVEL) 
                if ((lockedSensor == LOCK_SENSOR_RESET && unlockSensor == LOCK_SENSOR_RESET )|| unlockSensor == LOCK_SENSOR_SET) 
                {
                    LOCKDAI_LOG_W("wake 1 %d %d", lockedSensor, unlockSensor);
                    // 即将唤醒 重新读取一次，防止误判
                    Lock_WakeupUpdateSenser();

                    LOCKDAI_LOG_W("check 2 %d %d", lockedSensor, unlockSensor);

                    if ((lockedSensor == LOCK_SENSOR_RESET && unlockSensor == LOCK_SENSOR_RESET )|| unlockSensor == LOCK_SENSOR_SET) 
                    {
                        // 状态改变 机械旋钮转动
                        g_lockWakeFlag = SET; 
						
//                        GPIO_WakeupCheckPowerOn(OPTO_EN_PIN, RESET);
                        // LOCK_IR_DISABLE();
                        return 1;
                    }                
                }
            }
            // LOCK_IR_DISABLE();
            GPIO_WakeupCheckPowerOn(OPTO_EN_PIN, RESET);
			g_IrPowerSwitch = RESET; 
        }
    }
    return 0;
}

/**
 * @brief 设置光耦电源开关
 * 
 * @param ir_power_level :开关电平
 */
static void Lock_OptocoupleCtrl(uint8_t ir_power_level)
{
    if(ir_power_level == IR_POWER_DISABLE_LEVEL)//关光耦电源
    {       
        LOCK_IR_DISABLE();    
        g_IrPowerSwitch = RESET;   
    }
    else//开光耦电源
    {
        LOCK_IR_ENABLE(); 
        g_IrPowerSwitch = SET;  
        co_delay_ms(1);	 
    }
    LOCKDAI_LOG_V("ir switch:%d",g_IrPowerSwitch);
}

/**
 * @brief 获取自适应方向的标志位
 * 
 * @return 产测写入的自适应方向标志位 
 */
static uint8_t lock_CalflagGet(void)
{
    if (OSAL_NvRead(OSAL_OFFSET(LockNvData_stu_t, g_autoCalFlag), (void *)&lock_data.g_autoCalFlag,
                    sizeof(lock_data.g_autoCalFlag)) != SUCCESS)  // TODO 读取NV存储的电机方向
    {
        /*读取失败处理*/
    }
    if (lock_data.g_autoCalFlag != SET)
    {
        lock_data.g_autoCalFlag = RESET;
    }
    return lock_data.g_autoCalFlag;
}

/**
 * @brief 设置自适应方向的标志位
 * 
 * @param flag：1：设置自适应方向标志 0：清除自适应方向标志
 */
static void lock_CalflagSet(uint8_t flag)
{
    lock_data.g_autoCalFlag = flag;
    if (OSAL_NvWrite(OSAL_OFFSET(LockNvData_stu_t, g_autoCalFlag), (void *)&lock_data.g_autoCalFlag,
                     sizeof(lock_data.g_autoCalFlag)) != SUCCESS)
    {
        /*写入失败处理*/
    } 
}

/**
 * @brief 打开电机和光耦的锁体控制的配置
 * 
 */
static void Lock_CtrlOpen(void)
{
    Motor_Stop();
    /* 打开PWM和ADC */
    Device_Enable(MOTO_A_VIRTUAL_PWM);
    Device_Enable(MOTO_B_VIRTUAL_PWM);
    Device_Enable(LOCK_DCI_ADC_CHANNEL);
    /* 光耦电机通电 */
    LOCK_MOTOR_ENABLE();
    Lock_OptocoupleCtrl(IR_POWER_ENABLE_LEVEL);
	motorRunDelyOpen.StepCount=OPEN_CLOSE_DELAY_START;	
}


/**
 * @brief 关闭电机和光耦的锁体控制配置
 * 
 */
static void Lock_CtrlClose(void)
{
    
    //1.pwm关掉  2.配置普通GPIO，低电平停止电机
    Motor_Stop();
    /* 关闭PWM和ADC */
    Device_Disable(MOTO_A_VIRTUAL_PWM);
    Device_Disable(MOTO_B_VIRTUAL_PWM);
    Device_Disable(LOCK_DCI_ADC_CHANNEL);
    /* 光耦电机断电 */
    LOCK_MOTOR_DISABLE();
//    Lock_OptocoupleCtrl(IR_POWER_DISABLE_LEVEL);
	motorRunDelyClose.StepCount=OPEN_CLOSE_DELAY_START;
    LOCKDAI_LOG_D("Lock_CtrlClose:%d,%d",motorStatus.current);
}

/**
  * @brief  上报电机方向
  * @note   
  *
  * @param  flag：0: 左方向上锁（逆时针） 1:右方向上锁（顺时针）
  */
static void Lock_MotorDirReport(uint8_t flag)
{
    LockMsg_t lockMsg;
    memset(&lockMsg, 0, sizeof(lockMsg));
    if(flag)
    {
        lockMsg.lock = LOCK_ACTION_DIR_RIGHT;
    }
    else
    {
        lockMsg.lock = LOCK_ACTION_DIR_LEFT;
    }
    OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
}

/**
  * @brief  切换电机状态
  * @note   
  *
  * @param  status：需要切换的状态
  * @param  timeout：该状态的超时时间
  */
static void Lock_SwitchMotorStatus(MotorStatus_enum_t status, uint32_t timeout)
{
    isrPendFlag++;
    #ifdef STOP_TO_BRAKE
    MotorStatus_enum_t temp = status;//保存一份
    static MotorStatus_enum_t last_status = MOTOR_STA_IDLE;
    
    if ((MOTOR_STA_LOCKED_BRAKE == temp ||
            MOTOR_STA_UNLOCK_BRAKE == temp || 
			MOTOR_STA_LOCKED_BACK_BRAKE == temp ||
            MOTOR_STA_UNLOCK_BACK_BRAKE == temp ||
            MOTOR_STA_LOCKED_RESET_BRAKE == temp || 
            MOTOR_STA_UNLOCK_RESET_BRAKE == temp ))
    {
        status = MOTOR_STA_STOP;    
        last_status =  temp; 
    }
    else if((MOTOR_STA_STOP == temp) && (MOTOR_STA_LOCKED_BRAKE == last_status ||
            MOTOR_STA_UNLOCK_BRAKE == last_status || 
			MOTOR_STA_LOCKED_BACK_BRAKE == last_status ||
            MOTOR_STA_UNLOCK_BACK_BRAKE == last_status ||
            MOTOR_STA_LOCKED_RESET_BRAKE == last_status || 
            MOTOR_STA_UNLOCK_RESET_BRAKE == last_status ))
    {
        status = last_status;   
        last_status =  temp;  
        g_BrakeFlag =  ENABLE;
    }
    else
    {

        last_status =  MOTOR_STA_IDLE;  
    }
    #endif      
	motorStatus.current = status;
	motorStatus.timeout = timeout;
	motorStatus.startTime = OSAL_GetTickCount();

    LOCKDAI_LOG_D("motor action:%d",motorStatus.current);

    if (MOTOR_STA_LOCKED_BACK == motorStatus.current)
	{
        /* 上锁回拖 */
        Motor_TurnLeft();//上锁回拖操作跟开锁操作控制电机的方向是一致的
	}
    else if (MOTOR_STA_UNLOCK_BACK == motorStatus.current)
	{
        /* 开锁回拖 */
       // Motor_TurnRight();//开锁回拖操作跟上锁操作控制电机的方向是一致的
        Motor_TurnRight_test();//
    }
    else if (MOTOR_STA_LOCKED_RESET == motorStatus.current)
	{
        /* 上锁回位 */
        Motor_TurnLeft();//上锁回位操作跟开锁操作控制电机的方向是一致的
	}
    else if (MOTOR_STA_UNLOCK_RESET == motorStatus.current)
	{
        /* 开锁回位 */
        Motor_TurnRight();//开锁回位操作跟上锁操作控制电机的方向是一致的
    }
	else if (MOTOR_STA_LOCKED_BRAKE == motorStatus.current ||
            MOTOR_STA_UNLOCK_BRAKE == motorStatus.current || 
			MOTOR_STA_LOCKED_BACK_BRAKE == motorStatus.current ||
            MOTOR_STA_UNLOCK_BACK_BRAKE == motorStatus.current ||
            MOTOR_STA_LOCKED_RESET_BRAKE == motorStatus.current || 
            MOTOR_STA_UNLOCK_RESET_BRAKE == motorStatus.current )
	{
		/* 刹车 */
		Motor_Brake();
	}
	else if (MOTOR_STA_LOCKED == motorStatus.current)
	{
		/* 电机上锁 */
		Motor_TurnRight();
	}
	else if (MOTOR_STA_UNLOCK == motorStatus.current)
	{
		/* 电机开锁 */
		Motor_TurnLeft();
	}
	else
	{
		/* 电机停止 */
		Motor_Stop();
	}
    #ifdef STOP_TO_BRAKE
    motorStatus.current = temp;
    #endif       
    isrPendFlag--;
}

/**
  * @brief  处理上锁流程结束
  *         
  * @note   
  */
static void Lock_MotorLockedEnd(void)
{
    uint8_t repeatTotal; 
	uint8_t opt_vol;
    LockMsg_t lockMsg;
    memset(&lockMsg, 0, sizeof(lockMsg));
    
	if(lockCalibFlag == RESET) 
	{
		Lock_WakeupUpdateSenser();
	}
    
    LOCKDAI_LOG_D("lock hall&oc sta:%d,%d,lockCalibFlag=%d,g_IrPowerSwitch=%d\n", unlockSensor,lockedSensor,lockCalibFlag,g_IrPowerSwitch);
    //如果锁还没有完成校准,那么堵转后,需要同方向重试2次，再反方向重试3次,直到上锁成功才完成校准
    //如果锁已经完成了校准,那么堵转后只需要同方向再重试2次就可以了
    repeatTotal = (lockCalibFlag == RESET) ? (MOTOR_PARAM_MAX_REPEAT_TIMES * 2 - 1) : (MOTOR_PARAM_MAX_REPEAT_TIMES - 1);
    #if 1
    if (MOTOR_STA_STOP == motorStatus.current && (motorError==ERR_UNLOCK_DCI || motorError==ERR_LOCKED_DCI) && repeatCount >= repeatTotal) //解决堵转异常，无法开关锁
    {
            LOCKDAI_LOG_W("locked failed2");
            if(lockedSensor == LOCK_SENSOR_SET && lockedBack == RESET)    //堵转且处于关到位状态，则进行“回位”操作一次
            {
                motorError = ERR_NO_ERROR;
                lockedBack = SET;
                lockedBlock = RESET;
                Lock_SwitchMotorStatus(MOTOR_STA_LOCKED_BACK, motor_back_timeout);
            }
            else      //否则，处于异常状态，删除当前任务
            {
                //motorError = ERR_LOCK_ERROR;
                OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);
                lockMsg.lock = LOCK_ACTION_INVALID;//消息上报
                OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
                motorError = ERR_NO_ERROR;
                motorStatus.current = MOTOR_STA_IDLE;
                lockedBlock = RESET;
            }
            return;
    }
    #endif
    
    /* 发生堵塞了 */
    if(lockedBlock)
    {
        LOCKDAI_LOG_V("LockBlock:%d,%d,%d,lockCalibFlag=%d",lockedBlockPhase, repeatCount, repeatTotal,lockCalibFlag);
        #if 0
		if(lockedBlockPhase == LOCKED_BLOCK_INIT || lockedBlockPhase == LOCKED_BLOCK_LOCKED) //校准方向
        {
			LOCKDAI_LOG_I("LOCKED_BLOCK_INIT\r\n");
            lockedBlockPhase = LOCKED_BLOCK_UNLOCK;
            Lock_SwitchMotorStatus(MOTOR_STA_UNLOCK, MOTOR_PARAM_TURN_TIMEOUT);//开锁方向
            return;
        }
        #endif
        lockedBlock = RESET;
        
        if(repeatCount < repeatTotal)   //重新上锁次数没有超过规定次数，则重新上锁
        {
			// 0 1 换向(2 3 5） 
			repeatCount++;
			motorError = ERR_NO_ERROR;
//            lockedBack = RESET;
			if((lockCalibFlag == RESET))
			{
				if(lockedSensor == LOCK_SENSOR_SET)
				{
                    lockedBack = SET;
                    Lock_SwitchMotorStatus(MOTOR_STA_LOCKED_BACK, motor_back_timeout);
                    return;
				}
				else 
				{
					 Motor_ChangeDirection();
				}
			}			

			LOCKDAI_LOG_I("LOCKED_BLOCK_LOCKED ChangeDirectionD[%d]\r\n",repeatCount);
			lockedBlockPhase = LOCKED_BLOCK_LOCKED;//标记为上锁阶段
			Lock_SwitchMotorStatus(MOTOR_STA_LOCKED, MOTOR_PARAM_TURN_TIMEOUT);			  
        }
        else if(repeatCount == repeatTotal)//3次(或6次,视锁方向校准情况而定)上锁失败，则执行上锁回位操作(此时处于开锁状态了,只需执行开锁回拖即可) 
        {
            LOCKDAI_LOG_I("lock reset");   
            repeatCount++;
//            Lock_SwitchMotorStatus(MOTOR_STA_UNLOCK_BACK, MOTOR_PARAM_TURN_TIMEOUT); 
            if(lockedSensor==SET)   //需要回锁
            {
                motorError = ERR_NO_ERROR;
                Lock_SwitchMotorStatus(MOTOR_STA_LOCKED_BACK, MOTOR_PARAM_TURN_TIMEOUT); 
                lockedBack = SET;
            }
            else     //超次数，清除监控任务
            {        
                motorError = ERR_NO_ERROR;
                motorStatus.current = MOTOR_STA_IDLE;
                OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);
                
                lockMsg.lock = LOCK_ACTION_DCI_ERROR;//锁体过流
                OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
            }
        }
        else
        {
            LOCKDAI_LOG_W("locked failed");
            motorError = ERR_LOCK_ERROR;
            repeatCount = 0;
            OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);

            lockMsg.lock = LOCK_ACTION_INVALID;//消息上报
            OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));

            motorError = ERR_NO_ERROR;
            motorStatus.current = MOTOR_STA_IDLE;
        }
//        lockedBlock = RESET;
    }
    else // 没有发生堵塞
    {
		
        //上锁到位传感器(右光耦)未到位,有3种情况:
        //1.上锁超时,
        //2.上锁完成但未完成回拖时,右光耦到位后刹车时,旋钮逆时针回旋了一点,导致刹车停止后程序执行到此处时程序判断到右光耦未到位,此时需要回拖
        //3.上锁到位并回拖完成
        //if(backUnlockSensor == LOCK_SENSOR_RESET)//IR_LOCK没感应到
        if(lockedSensor == LOCK_SENSOR_SET) //上锁
        {

            if ( motorError == ERR_LOCKED_TIMEOUT  ) //1.上锁超时
            {
                LockMsg_t lockMsg;
                memset(&lockMsg, 0, sizeof(lockMsg));
                LOCKDAI_LOG_W("locked timeout");
                motorError = ERR_LOCK_ERROR;
                OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);

                lockMsg.lock = LOCK_ACTION_ABNORMAL;//消息上报
                OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));

                motorError = ERR_NO_ERROR;
                motorStatus.current = MOTOR_STA_IDLE;   
            }
            else
            {
                motorError = ERR_NO_ERROR;
                if(lockedBack == RESET)//2.情况2,需要执行回拖
                {
                    lockedBack = SET;
                    // lockMsg.lock = LOCK_ACTION_LOCKED_NO_BACK;//消息上报
                    // OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
                    Lock_SwitchMotorStatus(MOTOR_STA_LOCKED_BACK, motor_back_timeout);
                    return;
                }
				
                if ((lockCalibFlag == RESET) && lockedMode != LOCKED_MODE_TEST && (repeatCount != repeatTotal + 1))  // 校准方向不依赖开关锁流程是否成功//双向学习不成功回拖至开锁回拖位置实际失败
                {
                    LOCKDAI_LOG_I("calibrate finished 1");
					
                    lockMsg.lock = LOCK_ACTION_AUTO_DIR_CHECK_SUCCESS;//自学习成功
                    OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));

                    Motor_SaveDirection();

                    lockCalibFlag = SET;  // 上锁成功即是标记锁已完成校准
                    motorError    = ERR_NO_ERROR;
                    /* 上报上锁方向 */
                    Lock_MotorDirReport(Motor_GetDirection());

                    /* 更新上锁方向 */
                    if (Motor_GetDirection() == MOTO_DIR_CCW)  // 上锁方向为逆时针
                    {
                        lockedDir = LOCKED_DIR_CW;
                    }
                    else
                    {
                        lockedDir = LOCKED_DIR_CCW;
                    }
                    calib_st.b.Calib_Close_Delay = RESET;
                        
                }
                //3.上锁到位并回拖完成
                lockedBack = RESET;
                OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);
                // if(lockedSensor == LOCK_SENSOR_RESET)//此时还没有把门锁上,说明开锁失败 //
                // {
                //     LOCKDAI_LOG_W("locked failed");
                //     lockMsg.lock = LOCK_ACTION_INVALID;//消息上报
                //     OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
                // }
                // else//门锁上了,说明上锁成功
                {
                    LOCKDAI_LOG_I("locked succeed");
                    lockMsg.lock = LOCK_ACTION_LOCKED;//消息上报
                    OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
                }
                motorError = ERR_NO_ERROR;
                motorStatus.current = MOTOR_STA_IDLE;//标记锁的状态为空闲
            }
        }
		else if(lockedSensor==LOCK_SENSOR_RESET && unlockSensor==LOCK_SENSOR_RESET )
		{
			LOCKDAI_LOG_D("lockedSensor:%d,unlockSensor:%d", lockedSensor,unlockSensor);
            motorError = ERR_LOCK_ERROR;
            OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);

            lockMsg.lock = LOCK_ACTION_ABNORMAL;//消息上报
            OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));

            motorError = ERR_NO_ERROR;
            motorStatus.current = MOTOR_STA_IDLE;
		}
				#if 0
        //上锁传感器(右光耦)到位了，此处情况有2种: 
        //1.上次执行上锁操作,导致上锁到位了,此时需要执行回拖操作 
        //2.上次执行了回位操作,此时不需要执行回拖操作了 
        // else
        // {
        //     if(repeatCount == repeatTotal + 1)//情况2,不需要执行回拖操作
        //     {
        //         LOCKDAI_LOG_W("locked failed!");
        //         motorError = ERR_LOCK_ERROR;
        //         repeatCount = 0;
        //         OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);

        //         lockMsg.lock = LOCK_ACTION_INVALID;//消息上报
        //         OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));

        //         motorError = ERR_NO_ERROR;
        //         motorStatus.current = MOTOR_STA_IDLE;
        //     }
        //     else//情况1,需要执行回拖操作
        //     {
        //         if(g_current_step == LOCK_STEP_FOUND_DEST)
        //         {
        //             motorError = ERR_NO_ERROR;
        //             lockedBack = SET;
        //             Lock_SwitchMotorStatus(MOTOR_STA_LOCKED_BACK, motor_back_timeout);
        //         }
        //         else if(g_current_step == LOCK_STEP_BACKED)
        //         {
        //             OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);
        //             // if (lockedSensor == LOCK_SENSOR_RESET)  // 此时还没有把门锁上,说明开锁失败
        //             // {
        //             //     LOCKDAI_LOG_W("locked failed");
        //             //     lockMsg.lock = LOCK_ACTION_INVALID;  // 消息上报
        //             //     OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
        //             // }
        //             // else  // 门锁上了,说明上锁成功
        //             {
        //                 LOCKDAI_LOG_I("locked succeed");
        //                 lockMsg.lock = LOCK_ACTION_LOCKED;  // 消息上报
        //                 OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
        //             }
        //             motorError = ERR_NO_ERROR;
        //             motorStatus.current = MOTOR_STA_IDLE;  // 标记锁的状态为空闲
        //         }

        //     }
        // }
				#endif
    }
}

/**
  * @brief  处理开锁流程结束
  *         
  * @note   
  */
static void Lock_MotorUnlockEnd(void)
{
    uint8_t repeatTotal;
	  uint8_t opt_vol;
    LockMsg_t lockMsg;
    memset(&lockMsg, 0, sizeof(lockMsg));
    
    
    if(lockCalibFlag == RESET) 
	{
		Lock_WakeupUpdateSenser();
	}
    
    //如果锁还没有完成校准,那么堵转后,需要同方向重试2次，再反方向重试3次,直到开锁成功才完成校准
    //如果锁已经完成了校准,那么堵转后只需要同方向再重试2次就可以了
    repeatTotal = (lockCalibFlag == RESET) ? (MOTOR_PARAM_MAX_REPEAT_TIMES * 2 - 1) : (MOTOR_PARAM_MAX_REPEAT_TIMES - 1);
    LOCKDAI_LOG_D("unlock hall&oc sta:%d,%d,lockCalibFlag=%d;g_IrPowerSwitch=%d\n", unlockSensor,lockedSensor,lockCalibFlag,g_IrPowerSwitch);
    //开锁传感器(下光耦)未到位,有4种情况,
    //1.开锁堵塞
    //2.开锁超时  
    //3.开锁完成但未完成回拖时,下光耦到位后刹车时,旋钮逆时针或顺时针回旋了一点,导致刹车停止后程序执行到此处时程序判断到下光耦未到位,此时需要回拖
    //4.开锁到位并完成回拖

    //if(unlockSensor == LOCK_SENSOR_SET) //上锁//ok
    //if(unlockSensor == LOCK_SENSOR_SET)   //  打开会到开锁时，自学习一直err? 
    { 
        if ( motorError == ERR_UNLOCK_DCI )   //1.开锁堵塞了
        {
            unLockBack = RESET;
//            LOCKDAI_LOG_V("unlock repeat %d times",repeatCount);
            if(repeatCount < repeatTotal)   //重新开锁次数没有超过规定次数，则重新开锁
            {
							 
					repeatCount++;
					motorError = ERR_NO_ERROR;
//                    unLockBack = RESET;
					if((lockCalibFlag == RESET))
					{
						if(unlockSensor == LOCK_SENSOR_SET/* || lockedSensor == LOCK_SENSOR_SET*/) //初次開門，堵轉，表面狀態沒便，則改變動作方向
						{
							lockedBlockPhase = LOCKED_BLOCK_LOCKED;//标记为上锁阶段
							Lock_SwitchMotorStatus(MOTOR_STA_LOCKED, MOTOR_PARAM_TURN_TIMEOUT);
							return;
						}
						else //初次開門，就堵轉，則旋轉方向正確
						{
							Motor_ChangeDirection(); 
						}
					}				

					LOCKDAI_LOG_D("UNLOCK_BLOCK ChangeDirectionC[%d]\r\n",repeatCount);
					//lockedBlockPhase = LOCKED_BLOCK_UNLOCK;
					Lock_SwitchMotorStatus(MOTOR_STA_UNLOCK, MOTOR_PARAM_TURN_TIMEOUT);
								
            }
            else if(repeatCount == repeatTotal)//3次(或6次,视锁方向校准情况而定)开锁失败，则执行开锁回位操作
            {
                LOCKDAI_LOG_I("unLock Reset");
                repeatCount++;
                unLockBack = SET;
                Lock_SwitchMotorStatus(MOTOR_STA_UNLOCK_RESET, MOTOR_PARAM_TURN_TIMEOUT);
                lockMsg.lock = LOCK_ACTION_DCI_ERROR;//锁体过流
                OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
            }
            else
            {
                LOCKDAI_LOG_W("unlock failed 01");
                motorError = ERR_LOCK_ERROR;
                repeatCount = 0;
                OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);

				if (lockCalibFlag == RESET) 	
				lockMsg.lock = LOCK_ACTION_AUTO_DIR_CHECK_FAILED;//自学习失敗
				else
                lockMsg.lock = LOCK_ACTION_INVALID;//消息上报
                OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));

                motorError = ERR_NO_ERROR;
                motorStatus.current = MOTOR_STA_IDLE;
            }
        }
        else if ( motorError == ERR_UNLOCK_TIMEOUT ) //2.开锁超时,不需要执行回拖
        {
            LOCKDAI_LOG_W("unlock failed 02");
            motorError = ERR_LOCK_ERROR;
            OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);

            lockMsg.lock = LOCK_ACTION_ABNORMAL;//消息上报
            OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));

            motorError = ERR_NO_ERROR;
            motorStatus.current = MOTOR_STA_IDLE;
        }
        else
        {
	
            motorError = ERR_NO_ERROR;
            if(unLockBack == RESET)//3.情况3,需要执行回拖操作
            {

                unLockBack = SET;
                // lockMsg.lock = LOCK_ACTION_UNLOCK_NO_BACK;//消息上报
                // OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
                LOCKDAI_LOG_D("Lock_MotorUnlockEnd 001\n");
                Lock_SwitchMotorStatus(MOTOR_STA_UNLOCK_BACK, motor_back_timeout);
                return;
            }
            
            //4.开锁到位并回拖完成
            OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);

            if (lockCalibFlag == SET)  // 未校准状态不上报消息
            {
                if (unlockSensor == LOCK_SENSOR_RESET) // 此时还没有把门开锁,说明开锁失败//
                {
                    LOCKDAI_LOG_W("unlock failed 03");
                    lockMsg.lock = LOCK_ACTION_INVALID; // 消息上报
                    OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
                }
                else // 门锁上了,说明开锁成功
                {
                    LOCKDAI_LOG_I("unlock succeed");
                    lockMsg.lock = LOCK_ACTION_UNLOCK; // 消息上报
                    OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
                }
            }

            motorError = ERR_NO_ERROR;
            motorStatus.current = MOTOR_STA_IDLE;//标记锁的状态为空闲

            if (lockCalibFlag == RESET && lockedMode != LOCKED_MODE_TEST && (repeatCount != repeatTotal + 1))  // 校准方向不依赖开关锁流程是否成功
            {		
                LOCKDAI_LOG_I("calibrate finished 2");
//                Motor_SaveDirection();
                // lockCalibFlag = SET;  // 开锁成功即是标记锁已完成校准
                // motorError    = ERR_NO_ERROR;
                // /* 上报上锁方向 */
                // Lock_MotorDirReport(Motor_GetDirection());
                // /* 更新上锁方向 */
//                if (Motor_GetDirection() == MOTO_DIR_CCW)
//                {
//                    lockedDir = LOCKED_DIR_CW;
//                }
//                else
//                {
//                    lockedDir = LOCKED_DIR_CCW;
//                }

                // Lock_Ctrl_Sub(LOCK_CTRL_LOCKED);
                // 自学习 当前找到开锁位置 1S后执行上锁，找上锁位置
                OSAL_EventSingleCreate(COMP_LOCK, EVENT_LOCK_STUDY_DIR, (MOTOR_PARAM_NO_BRAKE_CHANGE_DIR_TIME + motor_back_timeout), EVT_PRIORITY_MEDIUM);
            }
        }
    }
		#if 0
    //开锁传感器(下光耦)到位了，此处情况有2种: 
    //1.上次执行开锁操作,导致开锁到位了,此时需要执行开锁回拖操作 
    //2.上次执行了开锁回位操作,此时不需要执行开锁回拖操作了
    // else//开锁传感器到位了,执行开锁回拖
    // {
    //     if(repeatCount == repeatTotal + 1)//情况2,不需要执行回拖操作
    //     {
    //         LOCKDAI_LOG_W("unlock failed 04");
    //         motorError = ERR_LOCK_ERROR;
    //         repeatCount = 0;
    //         OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);

    //         lockMsg.lock = LOCK_ACTION_INVALID;//消息上报
    //         OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));

    //         motorError = ERR_NO_ERROR;
    //         motorStatus.current = MOTOR_STA_IDLE;
    //     }
    //     else//情况1,需要执行回拖操作
    //     {
    //         if(g_current_step == LOCK_STEP_FOUND_DEST)
    //         {
    //             motorError = ERR_NO_ERROR;
    //             unLockBack = SET;
    //             Lock_SwitchMotorStatus(MOTOR_STA_UNLOCK_BACK, motor_back_timeout);
    //         }
    //         else if(g_current_step == LOCK_STEP_BACKED)
    //         {
    //             OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);
    //             if (unlockSensor == LOCK_SENSOR_RESET)  // 此时还没有把门开锁,说明开锁失败
    //             {
    //                 LOCKDAI_LOG_W("unlock failed 05");
    //                 lockMsg.lock = LOCK_ACTION_INVALID;  // 消息上报
    //                 OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
    //             }
    //             else  // 门锁上了,说明开锁成功
    //             {
    //                 LOCKDAI_LOG_I("unlock succeed");
    //                 lockMsg.lock = LOCK_ACTION_UNLOCK;  // 消息上报
    //                 OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
    //             }
    //             motorError = ERR_NO_ERROR;
    //             motorStatus.current = MOTOR_STA_IDLE;//标记锁的状态为空闲
    //         }

    //     }
    // }
		#endif
}

/**
  * @brief  传感器测试流程结束
  *         
  * @note   
  */
static void Lock_Hall_OC_Test_End(void)
{
    if(sensorTestSetp == SENSOR_TESTSETP_START)
    {
        sensorTestSetp = SENSOR_TESTSETP_END;
        Motor_SetDirection(MOTO_DIR_CCW);
        Lock_SwitchMotorStatus(MOTOR_STA_LOCKED, MOTOR_PARAM_TURN_TIMEOUT);
    }
    else if(sensorTestSetp == SENSOR_TESTSETP_END)
    {
        sensorTestSetp = SENSOR_TESTSETP_RESET;//CW
        Lock_SwitchMotorStatus(MOTOR_STA_UNLOCK, MOTOR_PARAM_TURN_TIMEOUT);
    }
    else if(sensorTestSetp == SENSOR_TESTSETP_RESET)
    {
        LockMsg_t lockMsg;        

        memset(&lockMsg, 0, sizeof(lockMsg));
        lockMsg.sensorTestStatus[0] = (uint8_t)sensorTestRet;  
 
        if(lockMsg.sensorTestStatus[0] == ((1<<HALL_CENTER) 
#if(LOCK_DAI_HALL_NUM != 1)
        | (1<<HALL_LEFT) 
        | (1<<HALL_RIGHT) 
#endif
        | (1<<OC_UNLUCK) | (1<<OC_LUCKED)| (1<<BLADE_LEFT) | (1<<BLADE_RIGHT)))
        {
            lockMsg.sensorTestStatus[1] = 0x00;
        } 
        else 
        {
            lockMsg.sensorTestStatus[1] = 0x05;//0x05,光耦挡片异常
        }
        OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));     //消息上报

        sensorTestSetp = SENSOR_TESTSETP_INIT;
        motorStatus.current = MOTOR_STA_IDLE;
        OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);
        LOCKDAI_LOG_D("hall oc blade test result:%d,%d",sensorTestRet,lockMsg.sensorTestStatus[1]);
    }
    LOCKDAI_LOG_D("sensorTestSetp :%d", sensorTestSetp);
}

/**
  * @brief  电机运行结束处理
  *         
  * @note   
  */
static void Lock_MotorTurnEnd(void)
{
	LockMsg_t lockMsg;
    memset(&lockMsg, 0, sizeof(lockMsg));
    
    if(lockedMode == LOCKED_MODE_HALL_OC_TEST)//传感器测试模式
    {
        Lock_Hall_OC_Test_End();
    }
    else
    { // motorError == ERR_BACK_TIMEOUT ||
        if (  motorError == ERR_BACK_DCI || motorError == ERR_RESET_TIMEOUT ||
            motorError == ERR_RESET_DCI) /* 产生了锁体回拖超时、回拖过流、回位超时、回位过流错误 */
        {
            LOCKDAI_LOG_W("back/reset error");
            OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);
            lockMsg.lock = LOCK_ACTION_INVALID;  //消息上报
            OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
            motorError          = ERR_NO_ERROR;
            motorStatus.current = MOTOR_STA_IDLE;
        }
        else if (lockStatus == LOCK_STA_LOCKING)
        {
            /* 处理上锁流程结束 */
            Lock_MotorLockedEnd();
        }
        else if (lockStatus == LOCK_STA_UNLOCKING)
        {
            /* 处理开锁流程结束 */
            Lock_MotorUnlockEnd();
        }
        // else //motorError == ERR_BACK_TIMEOUT  
        // {
        //     OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);
        //     lockMsg.lock = LOCK_ACTION_INVALID;  //消息上报 //
        //     OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
        //     motorError          = ERR_NO_ERROR;
        //     motorStatus.current = MOTOR_STA_IDLE;
        //      LOCKDAI_LOG_W("Lock_MotorTurnEnd error\n");
        // }
        if( (lockStatus == LOCK_STA_LOCKING || lockStatus == LOCK_STA_UNLOCKING) && (motorError == ERR_BACK_TIMEOUT)) //---
        {
            LOCKDAI_LOG_W(" error");
            OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);
            lockMsg.lock = LOCK_ACTION_INVALID;  //消息上报
            OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
            motorError          = ERR_NO_ERROR;
            motorStatus.current = MOTOR_STA_IDLE;
        }
    }


    if(motorStatus.current ==  MOTOR_STA_IDLE)
    {
        if (lockedMode != LOCKED_MODE_KEY_TEST)
        {
            Lock_CtrlClose();
        }
    }
}

/**
  * @brief  电机运行超时
  *         
  * @note   
  */
static void Lock_MotorTimeout(void)
{
	switch (motorStatus.current)
	{
		case MOTOR_STA_LOCKED:      //上锁超时
            motorError = ERR_LOCKED_TIMEOUT; 
            break;
		case MOTOR_STA_UNLOCK:      //开锁超时  
            motorError = ERR_UNLOCK_TIMEOUT; 
            break;
		case MOTOR_STA_LOCKED_BACK: //上锁回拖超时
            motorError = ERR_BACK_TIMEOUT;   
            break;
        case MOTOR_STA_UNLOCK_BACK: //开锁回拖超时
            motorError = ERR_BACK_TIMEOUT;   
            break;
        case MOTOR_STA_LOCKED_RESET: //上锁回位超时
            motorError = ERR_RESET_TIMEOUT;   
            break;
        case MOTOR_STA_UNLOCK_RESET: //开锁回位超时
            motorError = ERR_RESET_TIMEOUT;   
            break;
		default: 
            break;
	}
    LOCKDAI_LOG_I("motorError:%d", motorError);
    if (MOTOR_STA_STOP == motorStatus.current)         
	{
        if(g_BrakeFlag)//换向标志
        {
            g_BrakeFlag = DISABLE;
            Lock_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_CHANGE_DIR_TIME); 
        }
        else
        {
            /* 电机STOP 超时 *///
            Lock_MotorTurnEnd();
        }
    }
    else if (MOTOR_STA_LOCKED_BRAKE == motorStatus.current || 
            MOTOR_STA_UNLOCK_BRAKE == motorStatus.current||
            MOTOR_STA_LOCKED_BACK_BRAKE == motorStatus.current ||
            MOTOR_STA_UNLOCK_BACK_BRAKE == motorStatus.current)
	{
        /* 上锁/开锁刹车超时 */
        if(motorError == ERR_LOCKED_DCI)//上锁过流导致的刹车超时
        {
            Lock_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_BLOCKED_LOCKED_TIME);
        }
        else if(motorError == ERR_UNLOCK_DCI)//开锁过流导致的刹车超时
        {
            if(lockedBlock)//上锁堵塞过程中,开锁过流导致的刹车超时,设置为1000ms
            {
                Lock_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_BLOCKED_LOCKED_TIME);
            }
            else
            {
                Lock_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_BLOCKED_UNLOCK_TIME);
            }
        }
        else
        {
#ifdef STOP_TO_BRAKE
            Lock_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_BRAKE_TIME);//刹车
#else
            Lock_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_CHANGE_DIR_TIME);//刹车准备换向
#endif
        }
    }
    else
    {
		/* 上锁超时、开锁超时、回拖超时、*/
        Lock_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_STOP_TIME1);
    }
}

/**
  * @brief  检查电机电流
  *         
  * @note   只有以下三种电机状态，才需要检查电流：
  *         MOTOR_STA_LOCKED：上锁状态
  *         MOTOR_STA_UNLOCK：开锁状态
  *         MOTOR_STA_BACK：回拖状态
  */
static void Lock_MotorCheckDCI(void)
{
	int16_t adcValue;
	static uint8_t overflowCnt = 0;

	switch (motorStatus.current)
	{
		case MOTOR_STA_LOCKED: 
		case MOTOR_STA_UNLOCK: 
		case MOTOR_STA_LOCKED_BACK: 
        case MOTOR_STA_UNLOCK_BACK: 
            break;
		default: 
            return;
	}

    adcValue = (int16_t)Device_Read(LOCK_DCI_ADC_CHANNEL, NULL, 0, 0);
    if (adcValue >= MOTOR_PARAM_MAX_DCI_VALUE)
    {
        overflowCnt++;
        if (overflowCnt >= MOTOR_BLOCKED_FILETERED_TIMES)
        {
            LOCKDAI_LOG_D("block vol:%d ,motorStatus.current=%d", adcValue,motorStatus.current);
            overflowCnt = 0;
			
            /* 连续10次过流：标记错误情况，电机进入STOP状态 */
            if (motorStatus.current == MOTOR_STA_LOCKED)  // 上锁过流
            {
                motorError  = ERR_LOCKED_DCI;
                lockedBlock = SET;
#ifdef NO_BRAKE
                Lock_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_BLOCK_STOP_TIMEOUT);
#else
                Lock_SwitchMotorStatus(MOTOR_STA_LOCKED_BRAKE, MOTOR_PARAM_BRAKE_TIME);  // 上锁过流刹车
#endif

            }
            else if (motorStatus.current == MOTOR_STA_UNLOCK)  // 开锁过流
            {
                motorError = ERR_UNLOCK_DCI;
#ifdef NO_BRAKE
                Lock_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_BLOCK_STOP_TIMEOUT);
#else
                Lock_SwitchMotorStatus(MOTOR_STA_UNLOCK_BRAKE, MOTOR_PARAM_BRAKE_TIME);  // 开锁过流刹车
#endif
            }
            else if (motorStatus.current == MOTOR_STA_LOCKED_BACK || motorStatus.current == MOTOR_STA_UNLOCK_BACK)  // 回拖过流
            {
                motorError = ERR_BACK_DCI;
                Lock_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_BLOCK_STOP_TIMEOUT);  // 回拖过流停止
            }
            else if (motorStatus.current == MOTOR_STA_LOCKED_RESET || motorStatus.current == MOTOR_STA_UNLOCK_RESET)  // 回位过流
            {
                motorError = ERR_RESET_DCI;
#ifdef NO_BRAKE
                Lock_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_BLOCK_STOP_TIMEOUT);
#else
                Lock_SwitchMotorStatus(MOTOR_STA_LOCKED_BRAKE, MOTOR_PARAM_BRAKE_TIME);  // 回位过流刹车
#endif
            }
            else
            {
                Lock_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_BLOCK_STOP_TIMEOUT);
            }
        }
    }
    else
    {
        overflowCnt = 0;
    }
}

/**
  * @brief  电机运行状态监控（电机监控事件）
  *         
  * @note   监控电机电流、超时
  *         电机状态不等于MOTOR_STA_IDLE时：该函数每间隔10ms运行一次
  */
static void Lock_MotorMonitor(void)
{
    const uint32_t xTicks = OSAL_GetTickCount();
    uint32_t pastTime;
    pastTime = OSAL_PastTime(xTicks, motorStatus.startTime);    
	if (pastTime >= motorStatus.timeout)
	{
		Lock_MotorTimeout();    /* 处理电机当前状态超时 */
	}
	else if (pastTime >= MOTOR_PARAM_DCI_DETECT_DELAY_TIME)
	{
		Lock_MotorCheckDCI();   /* 检查电机运行电流（DCI） */
	}
}

/**
  * @brief  上锁接口函数
  *         
  * @note   
  */
static ErrorStatus Lock_Locked(void)
{
    //if (lockedSensor == LOCK_SENSOR_SET && backLockedSensor == LOCK_SENSOR_SET)//上锁到位,上锁回拖到位
   // if(lockedSensor == LOCK_SENSOR_SET && unlockSensor == LOCK_SENSOR_RESET)//门已锁上
   if(lockedSensor == LOCK_SENSOR_SET )
    {
        motorError = ERR_NO_ERROR;
        lockStatus = LOCK_STA_LOCKED;//已上锁
        LOCKDAI_LOG_D("Lock_Locked 001\n");
    }
    else
    {
        LOCKDAI_LOG_D("Lock_Locked 002\n");
        repeatCount = 0;
        lockStatus = LOCK_STA_LOCKING;
        Lock_CtrlOpen();
        OSAL_EventRepeatCreate(COMP_LOCK, EVENT_MOTOR_MONITOR, MOTOR_MONITOR_TIME, EVT_PRIORITY_HIGH);
        Lock_SwitchMotorStatus(MOTOR_STA_LOCKED, MOTOR_PARAM_TURN_TIMEOUT);
        return SUCCESS;
    }
    return ERROR;
}

/**
  * @brief  开锁接口函数
  *         
  * @note   
  */
static ErrorStatus Lock_Unlock(void)
{
    //if (unlockSensor == LOCK_SENSOR_SET)
    if(unlockSensor == LOCK_SENSOR_SET && lockedSensor == LOCK_SENSOR_RESET)//门已开锁
    {
        motorError = ERR_NO_ERROR;
        lockStatus = LOCK_STA_UNLOCK;//已开锁
        LOCKDAI_LOG_D("Lock_Unlock 001\n");
    }
    else
    {
        LOCKDAI_LOG_D("Lock_Unlock 002\n");
        repeatCount = 0;
        lockStatus = LOCK_STA_UNLOCKING;
        Lock_CtrlOpen();
        OSAL_EventRepeatCreate(COMP_LOCK, EVENT_MOTOR_MONITOR, MOTOR_MONITOR_TIME, EVT_PRIORITY_HIGH);
        Lock_SwitchMotorStatus(MOTOR_STA_UNLOCK, MOTOR_PARAM_TURN_TIMEOUT);
        return SUCCESS;
    }
    return ERROR;
}


/**
 * @brief Lock组件API函数类型
 * 
 */
static ErrorStatus Lock_Ctrl_Sub(LockCtrl_enum_t ctrl)
{
    LockMsg_t lockMsg;
	uint8_t CalibFlag=0;
    memset(&lockMsg, 0, sizeof(lockMsg));
    lockedMode = LOCKED_MODE_NORMAL;//标记为正常模式
    LOCKDAI_LOG_D("Lock_Ctrl:%d", ctrl);

    if (motorStatus.current != MOTOR_STA_IDLE)//非空闲状态下报锁体繁忙,不能执行锁体操作  // 
    {
        lockMsg.lock = LOCK_ACTION_BUSY;
        OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
        LOCKDAI_LOG_W("lock busy");
        return ERROR;
    }

	
    if(lockCalibFlag == RESET)//未校准状态,开关锁前,需要调用该函数
    {
        LOCKDAI_LOG_D("Not calibrate");//未校准

//#ifdef LR_DISTINGUISHABLE 
#if 1
        if(lockedDir == LOCKED_DIR_UNKNOWN)//上锁方向未知,以NV保存的上锁方向为准
        {			
			Motor_UpdateDirection();//沒校准时，更换方向				
        }   
        #if 0    
        else//已知上锁方向,此时需要设置电机的上锁方向  //不适用1霍尔2光耦项目的关锁霍尔逻辑
        {
            lockCalibFlag = SET;//直接设置为已经校准状态
            if(lockedDir == LOCKED_DIR_CW)//顺时针上锁
            {
                Motor_SetDirection(MOTO_DIR_CCW);
            }
            else
            {
                Motor_SetDirection(MOTO_DIR_CW);
            }
            Motor_SaveDirection();
            /* 上报上锁方向 */
            Lock_MotorDirReport(Motor_GetDirection());
        }
        #endif
#endif        
    }


	Lock_Init_Update_Senser();
	LOCKDAI_LOG_D(" opto power off Update_Senser key=%d",buttonFlage);	
    
    /* 变量置位 */
    g_current_step = LOCK_STEP_START;
    lockedBlock = RESET;
    lockedBlockPhase = LOCKED_BLOCK_INIT;
    unLockBack = RESET;
    Lock_WakeupUpdateSenser();//获取当前光耦状态
    if(lockedSensor == LOCK_SENSOR_SET)       {LOCKDAI_LOG_D("Door is closed");}
    else if(unlockSensor == LOCK_SENSOR_SET)  {LOCKDAI_LOG_D("Door is opened");}
    if(lockCalibFlag == SET &&(buttonFlage==USERS_TYPE_OPEN_KEY || buttonFlage==USERS_TYPE_CLOSE_KEY)) //只有按键开关锁，才进行处理
	{			
		
		LOCKDAI_LOG_D("Open_Close change=%02x;buttonFlag=%02x",ctrl,buttonFlage);

		if(lockedSensor == LOCK_SENSOR_SET /*&& ctrl==LOCK_CTRL_LOCKED*/)
		{
		    if(buttonFlage!=LOCKED_TIMING)
			{
				ctrl=LOCK_CTRL_UNLOCK;
			}
			else
			{
				ctrl=LOCK_CTRL_LOCKED;
			}
		}
		else if(unlockSensor == LOCK_SENSOR_SET /*&& ctrl==LOCK_CTRL_UNLOCK*/)
		{
			ctrl=LOCK_CTRL_LOCKED;
		}
		else 
		{
			ctrl=LOCK_CTRL_LOCKED;
		}
	}
    else  if(lockCalibFlag == RESET && buttonFlage!=0XFF)     //自学习过程， 外部开关锁，不执行
    {
        ctrl=0xff;
    }
    
    //if (!Device_Read(vPIN_C0, NULL, 0, 0))
    //{
        // 当前要执行锁体操作，光耦电源没开启，需要开启光耦电源更新锁体状态
//        LOCKDAI_LOG_D(" opto power off Update_Senser");
//        Lock_Init_Update_Senser();
    //}

    switch((uint8_t)ctrl)
    {
			case LOCK_CTRL_LOCKED:
			LOCKDAI_LOG_D(">>>>>>>lockedSensor:%d, unlockSensor:%d\n",lockedSensor, unlockSensor);
            if(lockedSensor == LOCK_SENSOR_SET && unlockSensor == LOCK_SENSOR_RESET)//门已锁上
            {
                LOCKDAI_LOG_D("LOCK_CTRL_LOCKED 001\n");
                lockMsg.lock = LOCK_ACTION_LOCKED;
                OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
            }
            else//门未锁上
            {
                LOCKDAI_LOG_D("LOCK_CTRL_LOCKED 002\n");
                Lock_Locked();
            }
            break;
			case LOCK_CTRL_UNLOCK:
			LOCKDAI_LOG_D("LOCK_CTRL_UNLOCK lockedSensor:%d, unlockSensor:%d\n",lockedSensor, unlockSensor);
				
            if(unlockSensor == LOCK_SENSOR_SET && lockedSensor == LOCK_SENSOR_RESET )//门已开锁
            {    
				LOCKDAI_LOG_D("LOCK_CTRL_UNLOCK 001[%d]\n",lockCalibFlag);	

				if(lockCalibFlag == RESET) //校準過程
				{
					LOCKDAI_LOG_D("LOCK_CTRL_LOCK 003\n");
                    
					Lock_Locked();
                    motorRunDelyClose.StepCount=OPEN_CLOSE_DELAY_START;
                    motorRunDelyOpen.StepCount=0xff;
                    calib_st.b.Calib_Close_Delay = SET;
				}
                else
                {
                    lockMsg.lock = LOCK_ACTION_UNLOCK;
                    OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
                }
            }
            else//门未开锁
            {
                LOCKDAI_LOG_D("LOCK_CTRL_UNLOCK 002\n");
                Lock_Unlock();
            }
            break; 
			case LOCK_CTRL_INVERSE:
            if(lockedSensor == LOCK_SENSOR_SET)//门已锁上,则执行开锁操作
            {
                Lock_Unlock();
            }
            else//其他状态,执行上锁操作
            {
                Lock_Locked();
            }
            break; 
			default:
            break;
    }
    buttonFlage=0xff;
    return SUCCESS;
}



void Ble_OpenCloseHandler(uint8_t typ)
{
//    ButtonMsg_t button;
//    strcpy(button.name, "BUT_CLOSE");
//    button.action = INPUT_PORT_STA_RELEASE;
//    button.times = 0;
//    OSAL_RingBufferWrite(rbHandle, &button);
//    /* 创建ISR事件 */
//    OSAL_EventCreateFromISR(COMP_BUTTON); 
    
//    if(typ==0x47) Lock_Ctrl_Sub(LOCK_CTRL_UNLOCK);
//    else if(typ==0x2e) Lock_Ctrl_Sub(LOCK_CTRL_LOCKED);
      //需要发开锁消息到上层，不能直接开锁操作，里面存在消息推送，导致异常重启
}

/**
  * @brief  产测模式操作上锁/开锁的接口
  * @note   
  *         
  * @param  testMode：测试模式, LOCK_UNLOCK_TEST_MODE:上锁/开锁测试 MOTOR_TEST_MODE:电机测试
  * @param  data：控制参数
  * @param  dataLen:控制参数的个数
  */
static uint16_t Lock_TestCtrl_Sub(Lock_Test_Mode_enum_t testMode, uint8_t data[], uint8_t dataLen)
{
    if(testMode == LOCK_UNLOCK_TEST_MODE)//上锁/开锁测试
    {
        LockMsg_t lockMsg;
        uint8_t ctrl = data[0];
        //uint8_t dir = data[1];

        memset(&lockMsg, 0, sizeof(lockMsg));
        lockedMode = LOCKED_MODE_TEST;          //标记为测试模式
        lockCalibFlag = RESET;                  //保证任意位置可开关锁
        if (motorStatus.current != MOTOR_STA_IDLE)//非空闲状态下报锁体繁忙,不能执行锁体操作
        {
            lockMsg.lock = LOCK_ACTION_BUSY;
            OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
            LOCKDAI_LOG_W("lock busy");
            return ERROR;
        }

        /* 变量置位 */
        g_current_step = LOCK_STEP_START;
        lockedBlock = RESET;
        lockedBlockPhase = LOCKED_BLOCK_INIT;
        lockedBack = RESET;
        unLockBack = RESET;
        switch((uint8_t)ctrl)
        {
            case LOCK_CTRL_LOCKED:
                if(lockedSensor == LOCK_SENSOR_SET)//门已锁上
                {
                    lockMsg.lock = LOCK_ACTION_LOCKED;
                    OSAL_MessagePublish(&lockMsg, sizeof(lockMsg)); 
                }
                else//门未锁上
                {
                    Lock_Locked();
                }
                break;
            case LOCK_CTRL_UNLOCK:
                if(unlockSensor == LOCK_SENSOR_SET)//门已开锁
                {
                    lockMsg.lock = LOCK_ACTION_UNLOCK;
                    OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
                }
                else//门未开锁
                {
                    Lock_Unlock();
                }
                break; 
            default:
                break;
        }
        return SUCCESS;
    }
    else if(testMode == MOTOR_TEST_MODE)//电机测试
    {
        if(dataLen < 1)//电机控制至少要有一个参数
        {
            return ERROR;
        }
        uint8_t motorCtrl = data[0];   
        if(motorCtrl != 0)
        {
            Lock_CtrlOpen();
            if(motorCtrl == 1)
            {
                Motor_TurnLeft();
            }
            if(motorCtrl == 2)
            {
                Motor_TurnRight();
            }
            if(motorCtrl == 3)
            {
                Motor_Stop();
            }
            return SUCCESS;
        }
    }
    else if(testMode == HALL_OC_TEST_MODE)//霍尔、光耦测试模式
    {
        LOCKDAI_LOG_D("entry hall oc blade test");
        g_current_step = LOCK_STEP_START;
        lockedMode = LOCKED_MODE_HALL_OC_TEST;          //标记为传感器测试模式
        sensorTestSetp = SENSOR_TESTSETP_START;         //标记为传感器测试模式的开始阶段
        sensorTestRet = 0;                              //刚开始时,测试结果清0
        Lock_CtrlOpen();
        Motor_SetDirection(MOTO_DIR_CW);                //先找初始位置
        OSAL_EventRepeatCreate(COMP_LOCK, EVENT_MOTOR_MONITOR, MOTOR_MONITOR_TIME, EVT_PRIORITY_HIGH);
        Lock_SwitchMotorStatus(MOTOR_STA_LOCKED, MOTOR_PARAM_TURN_TIMEOUT);
		return SUCCESS;
    }
    else if(testMode ==  KEY_TEST_MODE)
    {
        LOCKDAI_LOG_D("entry key test");
        lockedMode = LOCKED_MODE_KEY_TEST;
    }
    else if(testMode == SET_AUTO_CAL_FLAG_MODE)
    {
        lock_CalflagSet(SET);//设置自学习标志位
    }
    else
	{
		return SUCCESS;
	}
	return SUCCESS;
}


/**
 * @brief  校准方向、自动上锁
 * @note
 *
 *
 */
static void Lock_StartUp_Calibration(void)
{
    static FlagStatus flag = SET;

    if(lockCalibFlag == RESET)//未校准状态，需要进行自学习
    {
        if(calib_st.b.Msg_Open_Close==0x0f) calib_st.b.Msg_Open_Close = RESET; 
        Lock_OptocoupleCtrl(IR_POWER_ENABLE_LEVEL);
		Lock_WakeupUpdateSenser();
        if(unlockSensor == LOCK_SENSOR_SET) 
        {
            calib_st.b.Calib_Close_Delay = SET;//校准前，处于开锁状态，标志置位：关锁需要延迟
        }  
		LOCKDAI_LOG_D("unlockSensor=%d;%d;Calib_Close_Delay=%d\r\n",unlockSensor,lockedSensor,calib_st.b.Calib_Close_Delay);

		Lock_Ctrl_Sub(LOCK_CTRL_UNLOCK);
    }
}

/**
  * @brief  传感器状态改变
  * @note   检测到端口有动作就会调用该函数
  *         该函数会在中断里面以回调的形式调用
  *         
  * @param  name：端口名称
  * @param  status：端口状态
  * @param  times：连按次数
  */
static void Lock_SensorStatusChange(char *name, uint8_t status, uint8_t times)
{
    LockSensorAction_t sensor;
    memset(&sensor, 0, sizeof(sensor));

    /* 锁体传感器动作暂存缓存区 */
    strncpy(sensor.name, name,sizeof(sensor.name));
    sensor.action = (UserAction_enum_t)status;

    if(buttonFlage!=0xff) return;

    if(sensor.action > USER_ACTION_PRESS)// 
    {
        return;//过滤掉不需要的长按及拓展
    }
    LOCKDAI_LOG_V("I[%s,%d]",sensor.name,status);
    OSAL_RingBufferWrite(rbHandle, &sensor);
    if (isrPendFlag != 0)
    {
        return;
    }
    isrPendFlag++;
    /* 创建ISR事件 */
    OSAL_EventCreateFromISR(COMP_LOCK);
    isrPendFlag--;

}




void lock_step_found_dest_handle(uint8_t dest_type)
{
	if(dest_type==LOCK_STA_LOCKING)
	{
		   #ifdef CLOSE_TO_BRAKE //POSITION_DELAY_COMP //去掉刹车后，关锁不需要延迟
		   if(lockCalibFlag == SET || calib_st.b.Calib_Close_Delay==SET)
			{		
                LOCKDAI_LOG_D("LOCK_STEP_FOUND_DEST 001A>>>\n");
				if(motorRunDelyClose.StepCount==OPEN_CLOSE_DELAY_START)
				{
                    LOCKDAI_LOG_D("LOCK_STEP_FOUND_DEST Locking >>> adcValue=%d \n",(int16_t)Device_Read(LOCK_DCI_ADC_CHANNEL, NULL, 0, 0));
					motorRunDelyClose.index=MotoDelaySet(bat_vol);
					motorRunDelyClose.StepCount=CLOSE_DELAY_RUN;	
					LOCKDAI_LOG_D("LOCK_STEP_FOUND_DEST 001 >>> DelyClose=%d \n",motorOnOffDely[motorRunDelyClose.index].closeDelaytime);
					motorRunDelyClose.lockstatue=LOCK_STEP_FOUND_DEST;
					OSAL_TimerCreate(motoDelay_timer_handler, motorOnOffDely[motorRunDelyClose.index].closeDelaytime, RESET);
				}
			}
			else
			#endif
			{
				 LOCKDAI_LOG_D("LOCK_STEP_FOUND_DEST 001>>>\n");
				 if(motorRunDelyClose.StepCount!=CLOSE_DELAY_RUN)
                 {
                    g_current_step = LOCK_STEP_FOUND_DEST;  
                 }
			}
	}
	else if(dest_type==LOCK_STA_UNLOCKING)
	{
		   
		   #ifdef POSITION_DELAY_COMP
		   if(lockCalibFlag == SET)
			{
                LOCKDAI_LOG_D("LOCK_STEP_FOUND_DEST 003A>>>\n");
				if(motorRunDelyOpen.StepCount==OPEN_CLOSE_DELAY_START)
				{
                    LOCKDAI_LOG_D("LOCK_STEP_FOUND_DEST UnLocking >>> adcValue=%d \n",(int16_t)Device_Read(LOCK_DCI_ADC_CHANNEL, NULL, 0, 0));
					motorRunDelyOpen.index=MotoDelaySet(bat_vol);//MotoOVTarr();
					motorRunDelyOpen.StepCount=OPEN_DELAY_RUN;
					LOCKDAI_LOG_D("LOCK_STEP_FOUND_DEST 003>>> DelyOpen=%d\n",motorOnOffDely[motorRunDelyOpen.index].closeDelaytime);
					motorRunDelyOpen.lockstatue=LOCK_STEP_FOUND_DEST;
					OSAL_TimerCreate(motoDelay_timer_handler, motorOnOffDely[motorRunDelyOpen.index].closeDelaytime, RESET);
				}
			}
			else
		   #endif
			{
				 LOCKDAI_LOG_D("LOCK_STEP_FOUND_DEST 003>>>\n");
				 g_current_step = LOCK_STEP_FOUND_DEST;  
			}
	}
}



/**
  * @brief  传感器状态值更新
  * @note   检测到端口有动作就会调用该函数
  *         该函数会在中断里面以回调的形式调用
  *         
  */
static void Lock_SensorStatusUpdate(void)
{
    LockSensorAction_t sensor;
    LockMsg_t lockMsg;
    memset(&sensor, 0, sizeof(sensor));
    memset(&lockMsg, 0, sizeof(lockMsg));

    //TODO 处理传感器状态改变
    while (OSAL_RingBufferRead(rbHandle, &sensor) == SUCCESS)
    {
        LOCKDAI_LOG_V("U[%s,%d]", sensor.name, sensor.action);//U[IR_LOCKED,1]
        if(strcmp(sensor.name, "IR_LOCKED") == 0 || strcmp(sensor.name, "IR2_LOCKED") == 0)  //    IR_SECOND_LOCKED  || lockedSensor == LOCK_SENSOR_SET
        {
            #if 1
            if(strcmp(sensor.name, "IR_LOCKED") == 0)
            {    
                if(lockedMode == LOCKED_MODE_HALL_OC_TEST)//传感器测试模式
                {
                    sensorTestRet |= (1 << OC_LUCKED);
                }
                //更新关锁到位传感器状态
                if (g_IrPowerSwitch && sensor.action == USER_ACTION_PRESS)
                {
                    //backUnlockSensor = LOCK_SENSOR_SET;
                    leftLockedSensor = LOCK_SENSOR_SET;
                     LOCKDAI_LOG_V("IR_LOCKED 001\n");
                }
                else if (sensor.action == USER_ACTION_RELEASE) //g_IrPowerSwitch && 
                {
                    //backUnlockSensor = LOCK_SENSOR_RESET;
                    leftLockedSensor = LOCK_SENSOR_RESET;
                    LOCKDAI_LOG_V("IR_LOCKED 002\n");
                }
            }
            else if(strcmp(sensor.name, "IR2_LOCKED") == 0)
            {
                 if (g_IrPowerSwitch && sensor.action == USER_ACTION_PRESS)
                {
                    rightLockedSensor = LOCK_SENSOR_SET;
                    LOCKDAI_LOG_V("IR2_LOCKED 003\n");
                }
                else if (sensor.action == USER_ACTION_RELEASE) //g_IrPowerSwitch && 
                {
                    rightLockedSensor = LOCK_SENSOR_RESET;
                    LOCKDAI_LOG_V("IR2_LOCKED 004\n");
                }
            }

            // 左右上锁传感器两个都没上锁则没上锁,否则则是已上锁          
            if(leftLockedSensor == LOCK_SENSOR_RESET && rightLockedSensor == LOCK_SENSOR_RESET)
            {                  
                LOCKDAI_LOG_D("lockedSensor UnLOCK \n"); 
                lockedSensor = LOCK_SENSOR_RESET;                
            }
             else if((leftLockedSensor != LOCK_SENSOR_UNKNOW && rightLockedSensor != LOCK_SENSOR_UNKNOW))//修复中间位置学习问题
             {
                    LOCKDAI_LOG_D("lockedSensor LOCK\n");                    
					lockedSensor = LOCK_SENSOR_SET;
					unlockSensor = LOCK_SENSOR_RESET;// TODO:检查状态是否异常 -----
                    
                    if(calib_st.b.Calib_Close_Delay==SET) //校准完成关锁，增加关锁到位延迟
                    {
                       lock_step_found_dest_handle(LOCK_STA_LOCKING);
                       calib_st.b.Calib_Close_Delay=RESET;
                    }                    
             }
            #endif
            
            if(motorStatus.current == MOTOR_STA_IDLE && lockMsg.lock != LOCK_ACTION_LOCKED && lockedSensor==SET && calib_st.b.Msg_Open_Close == RESET)
            {
                    lockMsg.lock = LOCK_ACTION_LOCKED;   
                    OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));  
            }  
        }
        else if(strcmp(sensor.name, "IR_UNLOCK") == 0)
        {
            #if 1
            if(lockedMode == LOCKED_MODE_HALL_OC_TEST)//传感器测试模式
            {
                sensorTestRet |= (1 << OC_UNLUCK);
            }
            //更新上锁回拖到位传感器状态
            if ( sensor.action == USER_ACTION_PRESS) // g_IrPowerSwitch && --------
            {
                unlockSensor = LOCK_SENSOR_SET; //  backLockedSensor

                //lockedSensor = LOCK_SENSOR_RESET;
            }
            else if (sensor.action == USER_ACTION_RELEASE)
            { 
                unlockSensor = LOCK_SENSOR_RESET; //  backLockedSensor
            }
            LOCKDAI_LOG_D("unlockSensor:%d;,Msg_Open_Close=%d\n",unlockSensor,lockedSensor,calib_st.b.Msg_Open_Close);
            
            if(motorStatus.current == MOTOR_STA_IDLE && lockMsg.lock != LOCK_ACTION_UNLOCK && unlockSensor == LOCK_SENSOR_SET)
            {
                    if(calib_st.b.Msg_Open_Close == RESET)
                    {
                        lockMsg.lock = LOCK_ACTION_UNLOCK;
                        OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));  
                    }
            }
            else   
            {
                calib_st.b.Msg_Open_Close = RESET;
            }
            
//            Lock_StartUp_Calibration();
            
            // TODO: 上层发起自学习动作，底层判断是否需要执行自学习，若已学习成功，上报结果
            #endif 
        }     



        if(lockedMode ==  LOCKED_MODE_KEY_TEST)
        {
            OSAL_MessagePublish(&sensor, sizeof(sensor));
        }

        if (lockedMode != LOCKED_MODE_HALL_OC_TEST && lockStatus == LOCK_STA_LOCKING && motorStatus.current == MOTOR_STA_LOCKED)  //关锁到位
        {
            //if (lockedSensor == LOCK_SENSOR_SET && backUnlockSensor == LOCK_SENSOR_SET)
            if (lockedSensor == LOCK_SENSOR_SET)
            {
//                 g_current_step = LOCK_STEP_FOUND_DEST; 
				   lock_step_found_dest_handle(LOCK_STA_LOCKING);
            }
            else
            {
                LOCKDAI_LOG_D("LOCK_STEP_FOUND_DEST 002>>>\n");
            }
        }
        else if (lockedMode != LOCKED_MODE_HALL_OC_TEST && lockStatus == LOCK_STA_LOCKING && motorStatus.current == MOTOR_STA_UNLOCK)  //关时堵转切换开的方向
        {
            if (lockCalibFlag == RESET && unlockSensor == LOCK_SENSOR_SET && backUnlockSensor == LOCK_SENSOR_SET)//学习时堵转后切换方向到回拖位置再试
            {
                g_current_step = LOCK_STEP_BACKED;
            }
            else if (lockCalibFlag == SET && unlockSensor == LOCK_SENSOR_SET && backLockedSensor == LOCK_SENSOR_SET)//堵转锁舌缩回到位再试
            {
                g_current_step = LOCK_STEP_BACKED; 
            }
        }
        else if (lockedMode != LOCKED_MODE_HALL_OC_TEST && lockStatus == LOCK_STA_UNLOCKING && motorStatus.current == MOTOR_STA_UNLOCK) //开锁到位**
        {
            if (unlockSensor == LOCK_SENSOR_SET)
            {
//                g_current_step = LOCK_STEP_FOUND_DEST;
				  lock_step_found_dest_handle(LOCK_STA_UNLOCKING);
            }
            else
            {
                LOCKDAI_LOG_D("LOCK_STEP_FOUND_DEST 004>>>\n");
            }
            
        }
        // else if ((motorStatus.current == MOTOR_STA_LOCKED_BACK && backLockedSensor == LOCK_SENSOR_SET) || (motorStatus.current == MOTOR_STA_UNLOCK_BACK && backUnlockSensor == LOCK_SENSOR_SET))  // 回拖到位停止
        else if ((motorStatus.current == MOTOR_STA_LOCKED_BACK ) || (motorStatus.current == MOTOR_STA_UNLOCK_BACK) )  // 回拖到位停止
        {
            g_current_step = LOCK_STEP_BACKED;//
        }     
        else if (motorStatus.current == MOTOR_STA_LOCKED_RESET)
        {
            if (backUnlockSensor == LOCK_SENSOR_SET || (lockCalibFlag == SET && backLockedSensor == LOCK_SENSOR_SET))  // 上锁回位到位不刹车 backLockedSensor修复未堵死锁舌伸出一部分回位导致反向旋钮带电机的情况
            {
                g_current_step = LOCK_STEP_RESET;
            }
        }
        else if (motorStatus.current == MOTOR_STA_UNLOCK_RESET)
        {
            if (backLockedSensor == LOCK_SENSOR_SET || (lockCalibFlag == SET && backUnlockSensor == LOCK_SENSOR_SET) )  // 开锁回位到位不刹车 backUnlockSensor修复未堵死锁舌回缩一部分回位导致旋钮反向带电机的情况
            {
                g_current_step = LOCK_STEP_RESET;
            }
        }
        LOCKDAI_LOG_V("dir:%d sensor status:%d, %d, %d, %d",lockedDir,lockedSensor,backLockedSensor,unlockSensor,backUnlockSensor);
        
    }
//	OSAL_UpdateSleepTime(10000, 1);
}

/**
  * @brief  锁体启动
  *         
  * @note   
  */
static void Lock_Start(void)
{
    if (rbHandle == NULL)
    {
        /* 电机PWM配置 */
        Motor_PwmInit();
        /* 创建环形缓存（暂存传感器状态） */
        rbHandle = OSAL_RingBufferCreate(SENSOR_MAX_RING_LEN, sizeof(LockSensorAction_t));
            
        // 掉电2S后地磁需要知道开关锁方向重新初始化，否则会一直没初始化
        OSAL_EventSingleCreate(COMP_LOCK, EVENT_LOCK_DIR_UPDATE, 2000, EVT_PRIORITY_MEDIUM);//

        // for(uint8_t i = 0; i < sizeof(lock_data.version); i++)
        // {
        //     LOCKDAI_LOG_D("%c", lock_data.version[i]);
        // }
        // LOCKDAI_LOG_D("lock version:%s", lock_data.version);
        // < 版本
        OSAL_NvWrite(OSAL_OFFSET(LockNvData_stu_t, version), lock_data.version, sizeof(lock_data.version));
    }


    /* 注册锁体传感器端口 */
    InputPort_stu_t sensor_list[] = {
            {"IR_LOCKED",   vPIN_B20, OCEP2_SET_LEVEL, INPUT_PORT_FUNC_SINGLE}, //红外感应：上锁到位感应
            {"IR_UNLOCK",   vPIN_B21, OCEP1_SET_LEVEL, INPUT_PORT_FUNC_SINGLE}, //红外感应：开锁到位感应
            {"IR2_LOCKED",   vPIN_B33, OCEP3_SET_LEVEL, INPUT_PORT_FUNC_SINGLE}, //红外感应：上锁到位感应
#if(LOCK_DAI_HALL_NUM != 1)
            {"HALL_LEFT",   vPIN_B22, HALL1_SET_LEVEL, INPUT_PORT_FUNC_SINGLE}, //霍尔感应：上锁到位（旋钮位置：左）
#endif
#ifdef LR_DISTINGUISHABLE
            {"HALL_RIGHT", vPIN_B23, HALL3_SET_LEVEL, INPUT_PORT_FUNC_SINGLE}, //霍尔感应：开锁到位（旋钮位置：中间） 
#endif
            {"HALL_CENTER", vPIN_B24, HALL2_SET_LEVEL, INPUT_PORT_FUNC_SINGLE}, //霍尔感应：开锁到位（旋钮位置：中间）
    };
    InputPort_Registered(sensor_list, OSAL_LENGTH(sensor_list), Lock_SensorStatusChange);

    InputPort_EnableProt("IR_LOCKED");
    InputPort_EnableProt("IR2_LOCKED");
    InputPort_EnableProt("IR_UNLOCK");
#if(LOCK_DAI_HALL_NUM != 1)
    InputPort_EnableProt("HALL_LEFT");
#endif
#ifdef LR_DISTINGUISHABLE  
    InputPort_EnableProt("HALL_RIGHT");
#endif
    InputPort_EnableProt("HALL_CENTER");

    // LOCK_IR_ENABLE();
}
/**
 * @brief  自动上锁定时器回调
 * @param  timer: 
 */
static void Auto_Lock_TimerCb(TimerHandle_stu_t timer)
{
    // LOCKDAI_LOG_D("Auto_Lock_Timer CB \n");
    // Device_Write(vPIN_C0, NULL, 0, IR_POWER_ENABLE_LEVEL);
    OSAL_EventSingleCreate(COMP_LOCK, EVENT_AUTO_LOCK, AUTO_LOCK_EVENT_TIME, EVT_PRIORITY_HIGH);
    if (Auto_Lock_Timer != NULL)
    {
        OSAL_TimerDelete(Auto_Lock_Timer);
        Auto_Lock_Timer = NULL;
    }
}

static void Lock_Dai_ProcessMbox(uint8_t *msg)
{
    switch (msg[0])
    {
		case LOCK_MBOX_CTRL:
		{
			uint8_t ctrl;
			ctrl = msg[1];
			switch(msg[2])
			{
				case USERS_TYPE_PWD:
				case USERS_TYPE_OPEN_KEY:
                case USERS_TYPE_CLOSE_KEY:
				case USERS_TYPE_CARD:
				case USERS_TYPE_FPT:
				case USERS_TYPE_FACE:
				buttonFlage=msg[2];
				default:break;
			}
            LOCKDAI_LOG_D("msg[2]:%02X", msg[2]);
			Lock_Ctrl_Sub((LockCtrl_enum_t)ctrl);
		}
			break;
		case LOCK_MBOX_TESTCTRL:
		{
			uint8_t testMode, dataLen, data[10];
			testMode = msg[1];
			dataLen = msg[2];
			memcpy(data, &msg[3], dataLen);
			Lock_TestCtrl_Sub((Lock_Test_Mode_enum_t)testMode, data, dataLen);
		}
			break;
        case LOCK_MBOX_IR_CTRL:
        {  
            uint8_t ir_power_level;
            ir_power_level = msg[1];
            Lock_OptocoupleCtrl(ir_power_level);                      
        }
            break;
        case LOCK_MBOX_BATTERY:
        {
           
            memcpy(&bat_vol, &msg[1], sizeof(bat_vol));
            LOCKDAI_LOG_D("vol = %d", bat_vol);
			
            if (bat_vol >= MOTOR_POWER_CTRL_VAL)
            {
                LOCK_MOTOR_POWER_HIGH_VOLTAGE();
            }
            else
            {
                LOCK_MOTOR_POWER_LOW_VOLTAGE();
            }
			
		    if (MOTOR_STA_LOCKED_BACK == motorStatus.current)
			{
				motor_back_timeout=motorOnOffDely[MotoDelaySet(bat_vol)].backDelaytime;
			}
			else 
			{
				motor_back_timeout=motorOnOffDely[MotoDelaySet(bat_vol)].openbackDelaytime;	
			}
			
//            if (bat_vol >= MOTOR_BACK_VAL_LEVEL1)
//            {
//                motor_back_timeout = MOTOR_BACK_TIME_LEVEL1;
//            }
//            else if (bat_vol >= MOTOR_BACK_VAL_LEVEL2)
//            {
//                motor_back_timeout = MOTOR_BACK_TIME_LEVEL2;
//            }
//            else if (bat_vol >= MOTOR_BACK_VAL_LEVEL3)
//            {
//                motor_back_timeout = MOTOR_BACK_TIME_LEVEL3;
//            }
//            else
//            {
//                motor_back_timeout = MOTOR_BACK_TIME_LEVEL4;
//            }
        }
            break;
        case LOCK_MBOX_AUTO_LOCK:
        {
            uint8_t auto_lock_cmd = msg[1];
            uint32_t aoto_lock_time;
            memcpy(&aoto_lock_time, &msg[2], sizeof(aoto_lock_time));
            LOCKDAI_LOG_D("Auto lock %d,%d", auto_lock_cmd, aoto_lock_time);
            if (auto_lock_cmd == ENABLE_AUTO_LOCK)
            {
                if (Auto_Lock_Timer != NULL)
                {
                    OSAL_TimerDelete(Auto_Lock_Timer);
                    Auto_Lock_Timer = NULL;
                }
                Auto_Lock_Timer = OSAL_TimerCreate(Auto_Lock_TimerCb, aoto_lock_time, RESET); // 创建定时器

                if (Auto_Lock_Timer == NULL)
                {
                    LOCKDAI_LOG_W("Creat auto lock timer faild");
                }
            }
            else
            {
                if (Auto_Lock_Timer != NULL)
                {
                    OSAL_TimerDelete(Auto_Lock_Timer);
                    Auto_Lock_Timer = NULL;
                }
            }
        }
            break;
        case LOCK_MBOX_LOCK_MODE_SYNC:
        {  
            memcpy(&current_lockMode, &msg[1], sizeof(current_lockMode));
            LOCKDAI_LOG_D("current_lockMode = %d", current_lockMode);                     
        }
            break;

        case LOCK_MBOX_LOCK_SENSER_CHECK_WAKE:
        {  
            memcpy(&g_SleepSenserCheck, &msg[1], sizeof(g_SleepSenserCheck));
            LOCKDAI_LOG_D("Senser check flag = %d", g_SleepSenserCheck);                     
        }
            break;

        case LOCK_MBOX_SET_LOCK_DAI_DIR:
        {
            if (SUCCESS == OSAL_NvWrite(OSAL_OFFSET(LockNvData_stu_t, motor_direction), &msg[1], sizeof(lock_data.motor_direction)))
            {
                LOCKDAI_LOG_I("Lock Dir Set success %d", msg[1]);
            }
            else
            {
                LOCKDAI_LOG_W("Lock Dir Set error");
            }
        }
            break;
        default:
   
			break;
    }
}

/**
  * @brief  锁体休眠
  *         
  * @note   
  */
static void Lock_Sleep(void)
{
    LOCKDAI_LOG_I("Lock_Sleep");
    g_lockWakeFlag = RESET;
    // LOCKDAI_LOG_D("Lock_Init_Update_Senser %d %d %d %d", lockedSensor, unlockSensor);

    InputPort_DisableProt("IR_LOCKED");
    InputPort_DisableProt("IR2_LOCKED");
    InputPort_DisableProt("IR_UNLOCK");
    // /* 关闭PWM和ADC */
    Device_Disable(MOTO_A_VIRTUAL_PWM);
    Device_Disable(MOTO_B_VIRTUAL_PWM);
    Device_Disable(LOCK_DCI_ADC_CHANNEL);
    /* 光耦电机断电 */
//    LOCK_IR_DISABLE();
    Lock_OptocoupleCtrl(IR_POWER_DISABLE_LEVEL);
    LOCK_MOTOR_DISABLE();
    LOCK_MOTOR_POWER_SLEEP_VOLTAGE(); // 有功耗 休眠配置IO
    /* 休眠霍尔io配置 */
#if(LOCK_DAI_HALL_NUM != 1)    
    Device_Disable(SENSOR_HALL_LEFT);
#endif
#ifdef LR_DISTINGUISHABLE  
    Device_Disable(SENSOR_HALL_RIGHT);
#endif    
    Device_Disable(SENSOR_HALL_CENTER);
}



/**
 * @brief 切换方向
 * 
 */
static void Lock_SwitchDir(void)
{
    //TODO:简化判断逻辑
    if (g_current_step == LOCK_STEP_FOUND_DEST) //开关到位，进行刹车 / 停止
    {
        if (motorStatus.current == MOTOR_STA_LOCKED)
        {
#ifdef STOP_TO_BRAKE
            Lock_SwitchMotorStatus(MOTOR_STA_LOCKED_BRAKE, MOTOR_PARAM_STOP_TO_BRAKE_TIME);
#else		
#ifdef NO_BRAKE
			LOCKDAI_LOG_I("Lock_SwitchDir MOTOR_STA_LOCKED\n");
            Lock_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_NO_BRAKE_CHANGE_DIR_TIME);
#else
            Lock_SwitchMotorStatus(MOTOR_STA_LOCKED_BRAKE, MOTOR_PARAM_BRAKE_TIME);
#endif

#endif
        }
        else if (motorStatus.current == MOTOR_STA_UNLOCK)
        {
#ifdef STOP_TO_BRAKE
            Lock_SwitchMotorStatus(MOTOR_STA_UNLOCK_BRAKE, MOTOR_PARAM_STOP_TO_BRAKE_TIME);
#else
#ifdef NO_BRAKE
			LOCKDAI_LOG_I("Lock_SwitchDir MOTOR_STA_UNLOCK\n");
			
		#ifdef OPEN_TO_BRAKE
					Lock_SwitchMotorStatus(MOTOR_STA_UNLOCK_BRAKE, MOTOR_PARAM_BRAKE_TIME);
		#else
					Lock_SwitchMotorStatus(MOTOR_STA_UNLOCK_BRAKE, MOTOR_PARAM_BRAKE_TIME);
		#endif	
#else
            Lock_SwitchMotorStatus(MOTOR_STA_UNLOCK_BRAKE, MOTOR_PARAM_BRAKE_TIME);
#endif

#endif
        }     
    }
    else if (g_current_step == LOCK_STEP_BACKED)  // 回拖到位停止
    {
        if(motorStatus.current == MOTOR_STA_LOCKED_BACK)
        {
#ifdef STOP_TO_BRAKE
        Lock_SwitchMotorStatus(MOTOR_STA_LOCKED_BACK_BRAKE, MOTOR_PARAM_STOP_TO_BRAKE_TIME);
#else
#ifdef BACK_NO_BRAKE
        Lock_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_NO_BRAKE_CHANGE_DIR_TIME);
#else
        Lock_SwitchMotorStatus(MOTOR_STA_LOCKED_BACK_BRAKE, MOTOR_PARAM_BRAKE_TIME);
#endif

#endif          
        }
        else if(motorStatus.current == MOTOR_STA_UNLOCK_BACK)
        {
#ifdef STOP_TO_BRAKE
            Lock_SwitchMotorStatus(MOTOR_STA_UNLOCK_BACK_BRAKE, MOTOR_PARAM_STOP_TO_BRAKE_TIME);
#else
#ifdef BACK_NO_BRAKE
            Lock_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_NO_BRAKE_CHANGE_DIR_TIME);
#else
            Lock_SwitchMotorStatus(MOTOR_STA_UNLOCK_BACK_BRAKE, MOTOR_PARAM_BRAKE_TIME);
#endif

#endif
        }
        else if(motorStatus.current == MOTOR_STA_UNLOCK)
        {
            Lock_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_NO_BRAKE_CHANGE_DIR_TIME);
            g_current_step = LOCK_STEP_START;
        }
    }
    else if(g_current_step == LOCK_STEP_RESET)//上锁回位过程中检测到右光耦从未遮挡到遮挡状态则进行刹车
    {
        if (motorStatus.current == MOTOR_STA_LOCKED_RESET)
        {
#ifdef STOP_TO_BRAKE               
            Lock_SwitchMotorStatus(MOTOR_STA_LOCKED_RESET_BRAKE, MOTOR_PARAM_STOP_TO_BRAKE_TIME);
#else
#ifdef NO_BRAKE
            Lock_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_NO_BRAKE_CHANGE_DIR_TIME);
#else
            Lock_SwitchMotorStatus(MOTOR_STA_LOCKED_RESET_BRAKE, MOTOR_PARAM_BRAKE_TIME);
#endif       
#endif          
        }
        else if(motorStatus.current == MOTOR_STA_UNLOCK_RESET)
        {
#ifdef STOP_TO_BRAKE               
            Lock_SwitchMotorStatus(MOTOR_STA_UNLOCK_RESET_BRAKE, MOTOR_PARAM_STOP_TO_BRAKE_TIME);
#else
#ifdef NO_BRAKE
            Lock_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_NO_BRAKE_CHANGE_DIR_TIME);
#else
            Lock_SwitchMotorStatus(MOTOR_STA_UNLOCK_RESET_BRAKE, MOTOR_PARAM_BRAKE_TIME);
#endif
#endif                              
        }
    }
}







/**
  * @brief  更新锁开关锁到位传感器状态
  *         
  * @note   
  */
void Lock_Init_Update_Senser(void)
{
    if (lockCalibFlag)
    {
        LockMsg_t lockMsg;
        memset(&lockMsg, 0, sizeof(lockMsg));
        Lock_OptocoupleCtrl(IR_POWER_ENABLE_LEVEL);          
		LOCKDAI_LOG_D("Lock_Init_Update_Senser lockCalibFlag=%d", lockCalibFlag);	
        if (Device_Read(vPIN_B20, NULL, 0, 0) == OCEP1_SET_LEVEL || Device_Read(vPIN_B33, NULL, 0, 0) == OCEP1_SET_LEVEL)
        {
           lockedSensor = LOCK_SENSOR_SET;
        }
        else
        {
             lockedSensor = LOCK_SENSOR_RESET;
        }

				
        if (Device_Read(vPIN_B21, NULL, 0, 0) == OCEP1_SET_LEVEL)
        {
               unlockSensor = LOCK_SENSOR_SET;
        }
        else
        {
              unlockSensor = LOCK_SENSOR_RESET;
        }
        // TODO: 处理机械旋钮唤醒
        calib_st.b.Msg_Open_Close = RESET; 
        
        if (g_lockWakeFlag) //  
        {
            // 只需要识别开锁
            if ((lockedSensor == LOCK_SENSOR_RESET && unlockSensor == LOCK_SENSOR_RESET) || unlockSensor == LOCK_SENSOR_SET)
            {
                LOCKDAI_LOG_D("sleep wake up unlock\r\n");          
                lockMsg.lock = LOCK_ACTION_UNLOCK_MACH; // 消息上报 机械开锁成功

                if (lockedMode != LOCKED_MODE_KEY_TEST)
                {
                    OSAL_MessagePublish(&lockMsg, sizeof(lockMsg)); 
                }
            }
        }
        // LOCK_IR_DISABLE(); // 机械动作改变
    }
	else 
    {
		LOCKDAI_LOG_D("Lock_Init_Update_Senser %d %d dir=%d", lockedSensor, unlockSensor,inti_dir);
	}

}

static int32_t Lock_WakeHandle(uint32_t dev)
{
    LOCKDAI_LOG_I("Lock_WakeHandle !!!!!! %d \r\n",dev);

    return 1;
}

/**
 * @brief  锁体任务函数
 *
 * @note
 *
 * @param  event：当前任务的所有事件
 *
 * @return 返回未处理的事件
 */
static uint32_t Lock_Task(uint32_t event)
{
	/* 系统启动事件 */
	if (event & EVENT_SYS_START)
	{   
		LOCKDAI_LOG_I("Lock task start");
        Lock_OptocoupleCtrl(IR_POWER_ENABLE_LEVEL);
        Motor_UpdateDirection();
        calib_st.i=0;
        calib_st.b.Msg_Open_Close = SET;   //光感上电狀態變化不處理消息
        calib_st.b.Calib_Close_Delay = SET;
#ifndef SLAVE_DEVICE        
        SYS_API(Motor_LockMotorDirSet);
        SYS_API(Lock_get_lock_status);
#endif
        Lock_Start();	 
//        if (g_lockWakeFlag)
        {
            OSAL_EventSingleCreate(COMP_LOCK, EVENT_LOCK_SENSER_CHANGE_WAKE, 100, EVT_PRIORITY_MEDIUM);
        }
        return ( event ^ EVENT_SYS_START );
	}
	if (event & EVENT_SYS_MBOX)
    {
        uint8_t buffer[30] = {0};
        while (OSAL_MboxAccept(buffer))
        {
            Lock_Dai_ProcessMbox(buffer);
        }
        return ( event ^ EVENT_SYS_MBOX );
    }
	/* 系统休眠事件 */
	if (event & EVENT_SYS_SLEEP)
	{
        Lock_Sleep();
        // if (Auto_Lock_Timer != NULL)
        // {
        //     OSAL_TimerDelete(Auto_Lock_Timer);
        //     Auto_Lock_Timer = NULL;
        // }
        // Auto_Lock_Timer = OSAL_TimerCreate(Auto_Lock_TimerCb, 5000, RESET); // 创建定时器 aoto_lock_time

        // if (Auto_Lock_Timer == NULL)
        // {
        //     LOCKDAI_LOG_W("Creat auto lock timer faild");
        // }
        //  LOCKDAI_LOG_D("Creat auto lock timer ok\n");
		return ( event ^ EVENT_SYS_SLEEP );
	}
 
	/* 系统中断事件 */
	if (event & EVENT_SYS_ISR)
	{
        // TODO:处理光耦电源使能？
        Lock_SensorStatusUpdate();
		return ( event ^ EVENT_SYS_ISR );
	}

    /* 电机监控事件 */
    if (event & EVENT_MOTOR_MONITOR)
	{
        Lock_SwitchDir();
        Lock_MotorMonitor();
        if (motorStatus.current != MOTOR_STA_IDLE)//非空闲状态下不允许休眠///
        {
            OSAL_SetTaskStatus(TASK_STA_ACTIVE);
        }
        else
        {
            OSAL_SetTaskStatus(TASK_STA_NORMAL);
        }
        return ( event ^ EVENT_MOTOR_MONITOR );
    }
    /* 自动上锁事件 */
    if (event & EVENT_AUTO_LOCK)
    {
        LockMsg_t lockMsg;
        memset(&lockMsg, 0, sizeof(lockMsg));
        lockMsg.cmd = AUTO_LOCK_START;
        OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
        
        //Device_Write(vPIN_C0, NULL, 0, IR_POWER_DISABLE_LEVEL);
        LOCKDAI_LOG_D("EVENT_AUTO_LOCK:%d \n");
        return (event ^ EVENT_AUTO_LOCK);
    }

    if (event & EVENT_LOCK_DIR_UPDATE)
    {
        // 国芯前板启动慢，上电2S后才PUBLISH上锁方向
        LockMsg_t lockMsg;
        memset(&lockMsg, 0, sizeof(lockMsg));
        lockMsg.cmd = MSENSOR_REPORT_DIR;
        if (Motor_GetDirection())
        {
            lockMsg.lock = LOCK_ACTION_DIR_RIGHT;
        }
        else
        {
            lockMsg.lock = LOCK_ACTION_DIR_LEFT;
        }
        OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
        return (event ^ EVENT_LOCK_DIR_UPDATE);
    }

    /* 自学习找上锁方向事件 */
    if (event & EVENT_LOCK_STUDY_DIR)
    {
        LOCKDAI_LOG_D("EVENT_LOCK_STUDY_DIR");
        if(lockCalibFlag == RESET)
        {   calib_st.b.Calib_Close_Delay=SET; //标志置位：关锁需要延迟   
            Lock_Ctrl_Sub(LOCK_CTRL_LOCKED);
        }
        return (event ^ EVENT_LOCK_STUDY_DIR);
    }

    /* 上报锁状态事件 */
    if (event & EVENT_LOCK_SENSER_CHANGE_WAKE)
    {
        LOCKDAI_LOG_D("EVENT_LOCK_SENSER_CHANGE_WAKE");
        if(lockCalibFlag == SET && g_lockWakeFlag)
        {       
            Lock_Init_Update_Senser();
        } 
        calib_st.b.Msg_Open_Close = RESET;   
        return (event ^ EVENT_LOCK_SENSER_CHANGE_WAKE);
    }



    return 0;
}
COMPONENT_TASK_EXPORT(COMP_LOCK, Lock_Task, sizeof(LockNvData_stu_t));
COMPONENT_WAKEUP_EXPORT(COMP_LOCK, Lock_WakeHandle, vPIN_B33);//开锁光耦2
COMPONENT_WAKEUP_EXPORT(COMP_LOCK, Lock_WakeHandle, vPIN_B20);//上锁光耦
COMPONENT_WAKEUP_EXPORT(COMP_LOCK, Lock_WakeHandle, vPIN_B21);//开锁光耦

